MQTTVersion.c 5.8 KB

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