MQTTVersion.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*******************************************************************************
  2. * Copyright (c) 2012, 2020 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v2.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. * https://www.eclipse.org/legal/epl-2.0/
  10. * and the Eclipse Distribution License is available at
  11. * http://www.eclipse.org/org/documents/edl-v10.php.
  12. *
  13. * Contributors:
  14. * Ian Craggs - initial API and implementation and/or initial documentation
  15. *******************************************************************************/
  16. #include <stdio.h>
  17. #if !defined(_WRS_KERNEL)
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <fcntl.h>
  22. #include <sys/types.h>
  23. #include <ctype.h>
  24. #include "MQTTAsync.h"
  25. #if defined(_WIN32) || defined(_WIN64)
  26. #include <windows.h>
  27. #include <tchar.h>
  28. #include <io.h>
  29. #include <sys/stat.h>
  30. #define snprintf _snprintf
  31. #else
  32. #include <dlfcn.h>
  33. #include <sys/mman.h>
  34. #include <unistd.h>
  35. #endif
  36. /**
  37. *
  38. * @file
  39. * \brief MQTTVersion - display the version and build information strings for a library.
  40. *
  41. * With no arguments, we try to load and call the version string for the libraries we
  42. * know about: mqttv3c, mqttv3cs, mqttv3a, mqttv3as.
  43. * With an argument:
  44. * 1) we try to load the named library, call getVersionInfo and display those values.
  45. * 2) If that doesn't work, we look through the binary for eyecatchers, and display those.
  46. * This will work if the library is not executable in the current environment.
  47. *
  48. * */
  49. static const char* libraries[] = {"paho-mqtt3c", "paho-mqtt3cs", "paho-mqtt3a", "paho-mqtt3as"};
  50. static const char* eyecatchers[] = {"MQTTAsyncV3_Version", "MQTTAsyncV3_Timestamp",
  51. "MQTTClientV3_Version", "MQTTClientV3_Timestamp"};
  52. char* FindString(char* filename, const char* eyecatcher_input);
  53. int printVersionInfo(MQTTAsync_nameValue* info);
  54. int loadandcall(const char* libname);
  55. void printEyecatchers(char* filename);
  56. /**
  57. * Finds an eyecatcher in a binary file and returns the following value.
  58. * @param filename the name of the file
  59. * @param eyecatcher_input the eyecatcher string to look for
  60. * @return the value found - "" if not found
  61. */
  62. char* FindString(char* filename, const char* eyecatcher_input)
  63. {
  64. FILE* infile = NULL;
  65. static char value[100];
  66. const char* eyecatcher = eyecatcher_input;
  67. memset(value, 0, 100);
  68. if ((infile = fopen(filename, "rb")) != NULL)
  69. {
  70. size_t buflen = strlen(eyecatcher);
  71. char* buffer = (char*) malloc(buflen + 1); /* added space for unused null terminator to stop LGTM complaint */
  72. if (buffer != NULL)
  73. {
  74. int c = fgetc(infile);
  75. while (feof(infile) == 0)
  76. {
  77. int count = 0;
  78. buffer[count++] = c;
  79. if (memcmp(eyecatcher, buffer, buflen) == 0)
  80. {
  81. char* ptr = value;
  82. c = fgetc(infile); /* skip space */
  83. c = fgetc(infile);
  84. while (isprint(c))
  85. {
  86. *ptr++ = c;
  87. c = fgetc(infile);
  88. }
  89. break;
  90. }
  91. if (count == buflen)
  92. {
  93. memmove(buffer, &buffer[1], buflen - 1);
  94. count--;
  95. }
  96. c = fgetc(infile);
  97. }
  98. free(buffer);
  99. }
  100. fclose(infile);
  101. }
  102. return value;
  103. }
  104. int printVersionInfo(MQTTAsync_nameValue* info)
  105. {
  106. int rc = 0;
  107. while (info->name)
  108. {
  109. printf("%s: %s\n", info->name, info->value);
  110. info++;
  111. rc = 1; /* at least one value printed */
  112. }
  113. return rc;
  114. }
  115. typedef MQTTAsync_nameValue* (*func_type)(void);
  116. int loadandcall(const char* libname)
  117. {
  118. int rc = 0;
  119. MQTTAsync_nameValue* (*func_address)(void) = NULL;
  120. #if defined(_WIN32) || defined(_WIN64)
  121. HMODULE APILibrary = LoadLibraryA(libname);
  122. if (APILibrary == NULL)
  123. printf("Error loading library %s, error code %d\n", libname, GetLastError());
  124. else
  125. {
  126. func_address = (func_type)GetProcAddress(APILibrary, "MQTTAsync_getVersionInfo");
  127. if (func_address == NULL)
  128. func_address = (func_type)GetProcAddress(APILibrary, "MQTTClient_getVersionInfo");
  129. if (func_address)
  130. rc = printVersionInfo((*func_address)());
  131. FreeLibrary(APILibrary);
  132. }
  133. #else
  134. void* APILibrary = dlopen(libname, RTLD_LAZY); /* Open the Library in question */
  135. if (APILibrary == NULL)
  136. printf("Error loading library %s, error %s\n", libname, dlerror());
  137. else
  138. {
  139. *(void **) (&func_address) = dlsym(APILibrary, "MQTTAsync_getVersionInfo");
  140. if (func_address == NULL)
  141. func_address = dlsym(APILibrary, "MQTTClient_getVersionInfo");
  142. if (func_address)
  143. rc = printVersionInfo((*func_address)());
  144. dlclose(APILibrary);
  145. }
  146. #endif
  147. return rc;
  148. }
  149. #if !defined(ARRAY_SIZE)
  150. #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
  151. #endif
  152. void printEyecatchers(char* filename)
  153. {
  154. int i = 0;
  155. for (i = 0; i < ARRAY_SIZE(eyecatchers); ++i)
  156. {
  157. char* value = FindString(filename, eyecatchers[i]);
  158. if (value[0])
  159. printf("%s: %s\n", eyecatchers[i], value);
  160. }
  161. }
  162. int main(int argc, char** argv)
  163. {
  164. printf("MQTTVersion: print the version strings of an MQTT client library\n");
  165. printf("Copyright (c) 2012, 2018 IBM Corp.\n");
  166. if (argc == 1)
  167. {
  168. int i = 0;
  169. char namebuf[60];
  170. printf("Specify a particular library name if it is not in the current directory, or not executable on this platform\n");
  171. for (i = 0; i < ARRAY_SIZE(libraries); ++i)
  172. {
  173. #if defined(__CYGWIN__)
  174. snprintf(namebuf, sizeof(namebuf), "cyg%s-1.dll", libraries[i]);
  175. #elif defined(_WIN32) || defined(_WIN64)
  176. snprintf(namebuf, sizeof(namebuf), "%s.dll", libraries[i]);
  177. #elif defined(OSX)
  178. snprintf(namebuf, sizeof(namebuf), "lib%s.1.dylib", libraries[i]);
  179. #else
  180. snprintf(namebuf, sizeof(namebuf), "lib%s.so.1", libraries[i]);
  181. #endif
  182. printf("--- Trying library %s ---\n", libraries[i]);
  183. if (!loadandcall(namebuf))
  184. printEyecatchers(namebuf);
  185. }
  186. }
  187. else
  188. {
  189. if (!loadandcall(argv[1]))
  190. printEyecatchers(argv[1]);
  191. }
  192. return 0;
  193. }
  194. #else
  195. int main(void)
  196. {
  197. fprintf(stderr, "This tool is not supported on this platform yet.\n");
  198. return 1;
  199. }
  200. #endif /* !defined(_WRS_KERNEL) */