inifile.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "inifile.h"
  2. /**
  3. * @file inifile.c
  4. * @brief Handles reading and writing to blow.ini
  5. *
  6. * These functions implement a config file based on GLib GKeyFile
  7. * http://developer.gnome.org/glib/2.32/glib-Key-value-file-parser.html
  8. *
  9. * A normal blow.ini looks something like this:
  10. * @code
  11. * [EFNet:#zbr]
  12. * key=+OK IxH39/AbJUH/aRUx614KBmA.XkCgI/pV30Q.Fntj81tJF.Z1j3qP91n8Ogs1i.h0/1w2uqO0
  13. *
  14. * [EFNet:Jarbas]
  15. * key=+OK 1m4r7//QR9O10.bHc/J5I54/y31qm0eTQne1ztw170pz8500B16PD0G5C1G0/1gHm/QcANO/
  16. *
  17. * [FiSH]
  18. * ini_password_Hash=kHmWjS7BL+IffmLCJ+JWMj9y5r9mb+yioTm8oE/RmEw
  19. * @endcode
  20. */
  21. /**
  22. * Read a key from blow.ini
  23. * @param [in] section configuration value
  24. * @param [in] key configuration key
  25. * @param [in] default_value default value to write in buffer if something bad happens
  26. * @param [out] buffer key
  27. * @param [in] buflen length of buffer
  28. * @param [in] filepath file path to blow.ini
  29. * @return the length of the buffer
  30. *
  31. * Example Usage:
  32. * @code
  33. * char tmpKey[KEYBUF_SIZE]="";
  34. * char plainPrefix[20]="";
  35. *
  36. * // Reads the key for #zbr at EFNet
  37. * getIniValue("EFNet:#zbr", "key", "", tmpKey, KEYBUF_SIZE, iniPath);
  38. *
  39. * // Get the plain_prefix variable from the FiSH section, defaulting to "+p " if non-existant
  40. * getIniValue("FiSH", "plain_prefix", "+p ", plainPrefix, sizeof(plainPrefix), iniPath);
  41. * @endcode
  42. */
  43. int
  44. getIniValue(const char *section, const char *key, const char *default_value,
  45. char *buffer, int buflen, const char *filepath)
  46. {
  47. GKeyFile *key_file;
  48. GError *error = NULL;
  49. gchar *value = NULL;
  50. key_file = g_key_file_new();
  51. // If file was read OK...
  52. if ((int)
  53. g_key_file_load_from_file(key_file, filepath, G_KEY_FILE_NONE,
  54. NULL) == 1) {
  55. // If the record was found...
  56. value = g_key_file_get_string(key_file, section, key, &error);
  57. if (value != NULL && error == NULL) {
  58. strncpy(buffer, value, (size_t) buflen);
  59. buffer[buflen] = '\0';
  60. }
  61. }
  62. g_free(value);
  63. g_key_file_free(key_file);
  64. // In case of any error...
  65. if (error != NULL) {
  66. strncpy(buffer, default_value, (size_t) buflen);
  67. }
  68. return (int)strlen(buffer);
  69. }
  70. int getIniSize(const char *section, const char *key, const char *filepath)
  71. {
  72. GKeyFile *key_file;
  73. GError *error = NULL;
  74. gchar *value = NULL;
  75. int size = 1;
  76. key_file = g_key_file_new();
  77. if ((int)
  78. g_key_file_load_from_file(key_file, filepath, G_KEY_FILE_NONE,
  79. NULL) == 1) {
  80. value = g_key_file_get_string(key_file, section, key, &error);
  81. if (value != NULL && error == NULL) {
  82. size = strlen(value);
  83. }
  84. }
  85. g_free(value);
  86. g_key_file_free(key_file);
  87. return size;
  88. }
  89. int deleteIniValue(const char *section, const char *key, const char *filepath)
  90. {
  91. GKeyFile *key_file;
  92. GError *error = NULL;
  93. gsize num_keys = 0;
  94. int ret = 0;
  95. key_file = g_key_file_new();
  96. // If file was read OK...
  97. if ((int)
  98. g_key_file_load_from_file(key_file, filepath, G_KEY_FILE_NONE,
  99. NULL) == 1) {
  100. g_key_file_remove_key(key_file, section, key, &error);
  101. if (error == NULL) {
  102. // Check if group is empty, if it is, remove it also
  103. (void)g_key_file_get_keys(key_file, section, &num_keys,
  104. &error);
  105. if (error == NULL && num_keys == 0) {
  106. g_key_file_remove_group(key_file, section,
  107. NULL);
  108. }
  109. writeIniFile(key_file, filepath);
  110. ret = 1;
  111. } else {
  112. ret = 0;
  113. }
  114. }
  115. g_key_file_free(key_file);
  116. return ret;
  117. }
  118. /**
  119. * Write a key to blow.ini
  120. * @param [in] section configuration section
  121. * @param [in] key configuration key
  122. * @param [in] value value to write
  123. * @param [in] filepath file path to blow.ini
  124. * @return 1 if everything is ok -1 if not
  125. *
  126. * Example Usage:
  127. * @code
  128. * // Set the plain_prefix variable as "+zbr "
  129. * setIniValue("FiSH", "plain_prefix", "+zbr ", iniPath);
  130. * @endcode
  131. */
  132. int
  133. setIniValue(const char *section, const char *key, const char *value,
  134. const char *filepath)
  135. {
  136. GKeyFile *key_file;
  137. GError *error = NULL;
  138. key_file = g_key_file_new();
  139. (void)g_key_file_load_from_file(key_file, filepath, G_KEY_FILE_NONE,
  140. NULL);
  141. g_key_file_set_string(key_file, section, key, value);
  142. writeIniFile(key_file, filepath);
  143. g_key_file_free(key_file);
  144. if (error != NULL) {
  145. return -1;
  146. }
  147. return 1;
  148. }
  149. void writeIniFile(GKeyFile * key_file, const char *filepath)
  150. {
  151. gchar *config = NULL;
  152. GError *error = NULL;
  153. gsize length = 0;
  154. FILE *outfile = NULL;
  155. // Get the content of the config to a string...
  156. config = g_key_file_to_data(key_file, &length, &error);
  157. if (error == NULL) { // If everything is ok...
  158. outfile = fopen(filepath, "w");
  159. if (outfile != NULL) {
  160. (void)fwrite(config, sizeof(gchar), (size_t) length,
  161. outfile);
  162. (void)fclose(outfile);
  163. }
  164. }
  165. g_free(config);
  166. }
  167. struct IniValue
  168. allocateIni(const char *section, const char *key, const char *filepath)
  169. {
  170. struct IniValue iniValue;
  171. iniValue.iniKeySize = getIniSize(section, key, filepath);
  172. iniValue.keySize = (iniValue.iniKeySize * 2) * sizeof(char);
  173. iniValue.key = (char *)malloc(iniValue.keySize);
  174. return iniValue;
  175. }
  176. void freeIni(struct IniValue iniValue)
  177. {
  178. bzero(iniValue.key, iniValue.keySize);
  179. free(iniValue.key);
  180. }