redis-server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. data/LICENSE +38 -0
  2. data/README.md +33 -0
  3. data/bin/redis +114 -0
  4. data/redis/Makefile +5 -0
  5. data/redis/extconf.rb +3 -0
  6. data/redis/redis-2.2.11/00-RELEASENOTES +199 -0
  7. data/redis/redis-2.2.11/BUGS +1 -0
  8. data/redis/redis-2.2.11/CONTRIBUTING +13 -0
  9. data/redis/redis-2.2.11/COPYING +10 -0
  10. data/redis/redis-2.2.11/Changelog +1032 -0
  11. data/redis/redis-2.2.11/INSTALL +30 -0
  12. data/redis/redis-2.2.11/Makefile +22 -0
  13. data/redis/redis-2.2.11/README +83 -0
  14. data/redis/redis-2.2.11/TODO +4 -0
  15. data/redis/redis-2.2.11/client-libraries/README +11 -0
  16. data/redis/redis-2.2.11/deps/hiredis/COPYING +10 -0
  17. data/redis/redis-2.2.11/deps/hiredis/Makefile +115 -0
  18. data/redis/redis-2.2.11/deps/hiredis/README.md +311 -0
  19. data/redis/redis-2.2.11/deps/hiredis/TODO +2 -0
  20. data/redis/redis-2.2.11/deps/hiredis/adapters/ae.h +95 -0
  21. data/redis/redis-2.2.11/deps/hiredis/adapters/libev.h +113 -0
  22. data/redis/redis-2.2.11/deps/hiredis/adapters/libevent.h +76 -0
  23. data/redis/redis-2.2.11/deps/hiredis/async.c +321 -0
  24. data/redis/redis-2.2.11/deps/hiredis/async.h +112 -0
  25. data/redis/redis-2.2.11/deps/hiredis/example-ae.c +53 -0
  26. data/redis/redis-2.2.11/deps/hiredis/example-libev.c +47 -0
  27. data/redis/redis-2.2.11/deps/hiredis/example-libevent.c +48 -0
  28. data/redis/redis-2.2.11/deps/hiredis/example.c +67 -0
  29. data/redis/redis-2.2.11/deps/hiredis/fmacros.h +15 -0
  30. data/redis/redis-2.2.11/deps/hiredis/hiredis.c +1058 -0
  31. data/redis/redis-2.2.11/deps/hiredis/hiredis.h +170 -0
  32. data/redis/redis-2.2.11/deps/hiredis/net.c +170 -0
  33. data/redis/redis-2.2.11/deps/hiredis/net.h +43 -0
  34. data/redis/redis-2.2.11/deps/hiredis/sds.c +479 -0
  35. data/redis/redis-2.2.11/deps/hiredis/sds.h +77 -0
  36. data/redis/redis-2.2.11/deps/hiredis/test.c +479 -0
  37. data/redis/redis-2.2.11/deps/hiredis/util.h +40 -0
  38. data/redis/redis-2.2.11/deps/linenoise/Makefile +10 -0
  39. data/redis/redis-2.2.11/deps/linenoise/README.markdown +45 -0
  40. data/redis/redis-2.2.11/deps/linenoise/example.c +27 -0
  41. data/redis/redis-2.2.11/deps/linenoise/linenoise.c +609 -0
  42. data/redis/redis-2.2.11/deps/linenoise/linenoise.h +55 -0
  43. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER +214 -0
  44. data/redis/redis-2.2.11/design-documents/REDIS-CLUSTER-2 +343 -0
  45. data/redis/redis-2.2.11/doc/AppendCommand.html +48 -0
  46. data/redis/redis-2.2.11/doc/AppendOnlyFileHowto.html +41 -0
  47. data/redis/redis-2.2.11/doc/AuthCommand.html +39 -0
  48. data/redis/redis-2.2.11/doc/Benchmarks.html +129 -0
  49. data/redis/redis-2.2.11/doc/BgrewriteaofCommand.html +41 -0
  50. data/redis/redis-2.2.11/doc/BgsaveCommand.html +39 -0
  51. data/redis/redis-2.2.11/doc/BlpopCommand.html +51 -0
  52. data/redis/redis-2.2.11/doc/BrpoplpushCommand.html +39 -0
  53. data/redis/redis-2.2.11/doc/CommandReference.html +47 -0
  54. data/redis/redis-2.2.11/doc/Comparisons.html +42 -0
  55. data/redis/redis-2.2.11/doc/ConfigCommand.html +76 -0
  56. data/redis/redis-2.2.11/doc/Configuration.html +38 -0
  57. data/redis/redis-2.2.11/doc/ConnectionHandlingSidebar.html +36 -0
  58. data/redis/redis-2.2.11/doc/ControlCommandsSidebar.html +36 -0
  59. data/redis/redis-2.2.11/doc/Credits.html +38 -0
  60. data/redis/redis-2.2.11/doc/DbsizeCommand.html +38 -0
  61. data/redis/redis-2.2.11/doc/DelCommand.html +41 -0
  62. data/redis/redis-2.2.11/doc/DesignPatterns.html +37 -0
  63. data/redis/redis-2.2.11/doc/EventLibray.html +44 -0
  64. data/redis/redis-2.2.11/doc/ExistsCommand.html +42 -0
  65. data/redis/redis-2.2.11/doc/ExpireCommand.html +96 -0
  66. data/redis/redis-2.2.11/doc/FAQ.html +70 -0
  67. data/redis/redis-2.2.11/doc/Features.html +38 -0
  68. data/redis/redis-2.2.11/doc/FlushallCommand.html +39 -0
  69. data/redis/redis-2.2.11/doc/FlushdbCommand.html +39 -0
  70. data/redis/redis-2.2.11/doc/FromSqlToDataStructures.html +37 -0
  71. data/redis/redis-2.2.11/doc/GenericCommandsSidebar.html +36 -0
  72. data/redis/redis-2.2.11/doc/GetCommand.html +39 -0
  73. data/redis/redis-2.2.11/doc/GetbitCommand.html +39 -0
  74. data/redis/redis-2.2.11/doc/GetsetCommand.html +38 -0
  75. data/redis/redis-2.2.11/doc/HackingStrings.html +83 -0
  76. data/redis/redis-2.2.11/doc/HashCommandsSidebar.html +36 -0
  77. data/redis/redis-2.2.11/doc/Hashes.html +37 -0
  78. data/redis/redis-2.2.11/doc/HdelCommand.html +39 -0
  79. data/redis/redis-2.2.11/doc/HexistsCommand.html +39 -0
  80. data/redis/redis-2.2.11/doc/HgetCommand.html +39 -0
  81. data/redis/redis-2.2.11/doc/HgetallCommand.html +40 -0
  82. data/redis/redis-2.2.11/doc/HincrbyCommand.html +45 -0
  83. data/redis/redis-2.2.11/doc/HlenCommand.html +38 -0
  84. data/redis/redis-2.2.11/doc/HmgetCommand.html +40 -0
  85. data/redis/redis-2.2.11/doc/HmsetCommand.html +40 -0
  86. data/redis/redis-2.2.11/doc/HsetCommand.html +40 -0
  87. data/redis/redis-2.2.11/doc/HsetnxCommand.html +41 -0
  88. data/redis/redis-2.2.11/doc/IncrCommand.html +43 -0
  89. data/redis/redis-2.2.11/doc/InfoCommand.html +48 -0
  90. data/redis/redis-2.2.11/doc/IntroductionToRedisDataTypes.html +152 -0
  91. data/redis/redis-2.2.11/doc/KeysCommand.html +43 -0
  92. data/redis/redis-2.2.11/doc/LastsaveCommand.html +39 -0
  93. data/redis/redis-2.2.11/doc/LindexCommand.html +40 -0
  94. data/redis/redis-2.2.11/doc/ListCommandsSidebar.html +36 -0
  95. data/redis/redis-2.2.11/doc/Lists.html +42 -0
  96. data/redis/redis-2.2.11/doc/LlenCommand.html +41 -0
  97. data/redis/redis-2.2.11/doc/LpopCommand.html +41 -0
  98. data/redis/redis-2.2.11/doc/LrangeCommand.html +47 -0
  99. data/redis/redis-2.2.11/doc/LremCommand.html +41 -0
  100. data/redis/redis-2.2.11/doc/LsetCommand.html +38 -0
  101. data/redis/redis-2.2.11/doc/LtrimCommand.html +47 -0
  102. data/redis/redis-2.2.11/doc/MgetCommand.html +52 -0
  103. data/redis/redis-2.2.11/doc/MonitorCommand.html +63 -0
  104. data/redis/redis-2.2.11/doc/MoveCommand.html +42 -0
  105. data/redis/redis-2.2.11/doc/MsetCommand.html +44 -0
  106. data/redis/redis-2.2.11/doc/MultiExecCommand.html +166 -0
  107. data/redis/redis-2.2.11/doc/NonexistentCommands.html +51 -0
  108. data/redis/redis-2.2.11/doc/ObjectHashMappers.html +39 -0
  109. data/redis/redis-2.2.11/doc/Pipelining.html +36 -0
  110. data/redis/redis-2.2.11/doc/ProgrammingExamples.html +38 -0
  111. data/redis/redis-2.2.11/doc/ProtocolSpecification.html +137 -0
  112. data/redis/redis-2.2.11/doc/PublishSubscribe.html +115 -0
  113. data/redis/redis-2.2.11/doc/QuickStart.html +68 -0
  114. data/redis/redis-2.2.11/doc/QuitCommand.html +38 -0
  115. data/redis/redis-2.2.11/doc/README.html +119 -0
  116. data/redis/redis-2.2.11/doc/RandomkeyCommand.html +39 -0
  117. data/redis/redis-2.2.11/doc/Redis0100ChangeLog.html +67 -0
  118. data/redis/redis-2.2.11/doc/Redis0900ChangeLog.html +56 -0
  119. data/redis/redis-2.2.11/doc/RedisBigData.html +61 -0
  120. data/redis/redis-2.2.11/doc/RedisCLI.html +37 -0
  121. data/redis/redis-2.2.11/doc/RedisEventLibrary.html +70 -0
  122. data/redis/redis-2.2.11/doc/RedisGuides.html +37 -0
  123. data/redis/redis-2.2.11/doc/RedisInternals.html +38 -0
  124. data/redis/redis-2.2.11/doc/RedisPipelining.html +93 -0
  125. data/redis/redis-2.2.11/doc/RedisStatus.html +56 -0
  126. data/redis/redis-2.2.11/doc/Redis_1_2_0_Changelog.html +40 -0
  127. data/redis/redis-2.2.11/doc/Redis_2_0_0_Changelog.html +62 -0
  128. data/redis/redis-2.2.11/doc/Redis_2_0_Whats_new.html +59 -0
  129. data/redis/redis-2.2.11/doc/RenameCommand.html +39 -0
  130. data/redis/redis-2.2.11/doc/RenamenxCommand.html +42 -0
  131. data/redis/redis-2.2.11/doc/ReplicationHowto.html +43 -0
  132. data/redis/redis-2.2.11/doc/ReplyTypes.html +42 -0
  133. data/redis/redis-2.2.11/doc/RoadMap.html +38 -0
  134. data/redis/redis-2.2.11/doc/RpoplpushCommand.html +44 -0
  135. data/redis/redis-2.2.11/doc/RpushCommand.html +40 -0
  136. data/redis/redis-2.2.11/doc/SaddCommand.html +41 -0
  137. data/redis/redis-2.2.11/doc/SaveCommand.html +39 -0
  138. data/redis/redis-2.2.11/doc/ScardCommand.html +41 -0
  139. data/redis/redis-2.2.11/doc/SdiffCommand.html +45 -0
  140. data/redis/redis-2.2.11/doc/SdiffstoreCommand.html +38 -0
  141. data/redis/redis-2.2.11/doc/SelectCommand.html +39 -0
  142. data/redis/redis-2.2.11/doc/SetCommand.html +39 -0
  143. data/redis/redis-2.2.11/doc/SetCommandsSidebar.html +36 -0
  144. data/redis/redis-2.2.11/doc/SetbitCommand.html +45 -0
  145. data/redis/redis-2.2.11/doc/SetexCommand.html +42 -0
  146. data/redis/redis-2.2.11/doc/SetnxCommand.html +51 -0
  147. data/redis/redis-2.2.11/doc/SetrangeCommand.html +58 -0
  148. data/redis/redis-2.2.11/doc/Sets.html +36 -0
  149. data/redis/redis-2.2.11/doc/ShutdownCommand.html +39 -0
  150. data/redis/redis-2.2.11/doc/SideBar.html +36 -0
  151. data/redis/redis-2.2.11/doc/SinterCommand.html +40 -0
  152. data/redis/redis-2.2.11/doc/SinterstoreCommand.html +39 -0
  153. data/redis/redis-2.2.11/doc/SismemberCommand.html +42 -0
  154. data/redis/redis-2.2.11/doc/SlaveofCommand.html +41 -0
  155. data/redis/redis-2.2.11/doc/SmembersCommand.html +38 -0
  156. data/redis/redis-2.2.11/doc/SmoveCommand.html +44 -0
  157. data/redis/redis-2.2.11/doc/SortCommand.html +75 -0
  158. data/redis/redis-2.2.11/doc/SortedSetCommandsSidebar.html +36 -0
  159. data/redis/redis-2.2.11/doc/SortedSets.html +36 -0
  160. data/redis/redis-2.2.11/doc/Speed.html +38 -0
  161. data/redis/redis-2.2.11/doc/SponsorshipHistory.html +38 -0
  162. data/redis/redis-2.2.11/doc/SpopCommand.html +40 -0
  163. data/redis/redis-2.2.11/doc/SrandmemberCommand.html +40 -0
  164. data/redis/redis-2.2.11/doc/SremCommand.html +42 -0
  165. data/redis/redis-2.2.11/doc/StringCommandsSidebar.html +36 -0
  166. data/redis/redis-2.2.11/doc/Strings.html +37 -0
  167. data/redis/redis-2.2.11/doc/StrlenCommand.html +39 -0
  168. data/redis/redis-2.2.11/doc/SubstrCommand.html +52 -0
  169. data/redis/redis-2.2.11/doc/SunionCommand.html +40 -0
  170. data/redis/redis-2.2.11/doc/SunionstoreCommand.html +38 -0
  171. data/redis/redis-2.2.11/doc/SupportedLanguages.html +60 -0
  172. data/redis/redis-2.2.11/doc/SupportedPlatforms.html +37 -0
  173. data/redis/redis-2.2.11/doc/TemplateCommand.html +38 -0
  174. data/redis/redis-2.2.11/doc/TtlCommand.html +38 -0
  175. data/redis/redis-2.2.11/doc/TwitterAlikeExample.html +250 -0
  176. data/redis/redis-2.2.11/doc/TypeCommand.html +46 -0
  177. data/redis/redis-2.2.11/doc/UnstableSource.html +39 -0
  178. data/redis/redis-2.2.11/doc/VirtualMemorySpecification.html +156 -0
  179. data/redis/redis-2.2.11/doc/VirtualMemoryUserGuide.html +66 -0
  180. data/redis/redis-2.2.11/doc/ZaddCommand.html +43 -0
  181. data/redis/redis-2.2.11/doc/ZcardCommand.html +41 -0
  182. data/redis/redis-2.2.11/doc/ZincrbyCommand.html +42 -0
  183. data/redis/redis-2.2.11/doc/ZrangeCommand.html +42 -0
  184. data/redis/redis-2.2.11/doc/ZrangebyscoreCommand.html +77 -0
  185. data/redis/redis-2.2.11/doc/ZrankCommand.html +43 -0
  186. data/redis/redis-2.2.11/doc/ZremCommand.html +42 -0
  187. data/redis/redis-2.2.11/doc/ZremrangebyrankCommand.html +39 -0
  188. data/redis/redis-2.2.11/doc/ZremrangebyscoreCommand.html +39 -0
  189. data/redis/redis-2.2.11/doc/ZscoreCommand.html +41 -0
  190. data/redis/redis-2.2.11/doc/ZunionCommand.html +42 -0
  191. data/redis/redis-2.2.11/doc/ZunionstoreCommand.html +43 -0
  192. data/redis/redis-2.2.11/doc/index.html +43 -0
  193. data/redis/redis-2.2.11/doc/redis.png +0 -0
  194. data/redis/redis-2.2.11/doc/style.css +25 -0
  195. data/redis/redis-2.2.11/redis.conf +417 -0
  196. data/redis/redis-2.2.11/src/Makefile +177 -0
  197. data/redis/redis-2.2.11/src/adlist.c +325 -0
  198. data/redis/redis-2.2.11/src/adlist.h +92 -0
  199. data/redis/redis-2.2.11/src/ae.c +390 -0
  200. data/redis/redis-2.2.11/src/ae.h +117 -0
  201. data/redis/redis-2.2.11/src/ae_epoll.c +91 -0
  202. data/redis/redis-2.2.11/src/ae_kqueue.c +93 -0
  203. data/redis/redis-2.2.11/src/ae_select.c +72 -0
  204. data/redis/redis-2.2.11/src/anet.c +347 -0
  205. data/redis/redis-2.2.11/src/anet.h +57 -0
  206. data/redis/redis-2.2.11/src/aof.c +675 -0
  207. data/redis/redis-2.2.11/src/config.c +627 -0
  208. data/redis/redis-2.2.11/src/config.h +64 -0
  209. data/redis/redis-2.2.11/src/db.c +543 -0
  210. data/redis/redis-2.2.11/src/debug.c +314 -0
  211. data/redis/redis-2.2.11/src/dict.c +721 -0
  212. data/redis/redis-2.2.11/src/dict.h +156 -0
  213. data/redis/redis-2.2.11/src/fmacros.h +15 -0
  214. data/redis/redis-2.2.11/src/help.h +638 -0
  215. data/redis/redis-2.2.11/src/intset.c +422 -0
  216. data/redis/redis-2.2.11/src/intset.h +19 -0
  217. data/redis/redis-2.2.11/src/lzf.h +100 -0
  218. data/redis/redis-2.2.11/src/lzfP.h +159 -0
  219. data/redis/redis-2.2.11/src/lzf_c.c +295 -0
  220. data/redis/redis-2.2.11/src/lzf_d.c +150 -0
  221. data/redis/redis-2.2.11/src/mkreleasehdr.sh +9 -0
  222. data/redis/redis-2.2.11/src/multi.c +268 -0
  223. data/redis/redis-2.2.11/src/networking.c +899 -0
  224. data/redis/redis-2.2.11/src/object.c +484 -0
  225. data/redis/redis-2.2.11/src/pqsort.c +197 -0
  226. data/redis/redis-2.2.11/src/pqsort.h +15 -0
  227. data/redis/redis-2.2.11/src/pubsub.c +267 -0
  228. data/redis/redis-2.2.11/src/rdb.c +1020 -0
  229. data/redis/redis-2.2.11/src/redis-benchmark.c +530 -0
  230. data/redis/redis-2.2.11/src/redis-check-aof.c +185 -0
  231. data/redis/redis-2.2.11/src/redis-check-dump.c +681 -0
  232. data/redis/redis-2.2.11/src/redis-cli.c +773 -0
  233. data/redis/redis-2.2.11/src/redis.c +1677 -0
  234. data/redis/redis-2.2.11/src/redis.h +1022 -0
  235. data/redis/redis-2.2.11/src/release.c +13 -0
  236. data/redis/redis-2.2.11/src/replication.c +557 -0
  237. data/redis/redis-2.2.11/src/sds.c +639 -0
  238. data/redis/redis-2.2.11/src/sds.h +78 -0
  239. data/redis/redis-2.2.11/src/sha1.c +276 -0
  240. data/redis/redis-2.2.11/src/sha1.h +17 -0
  241. data/redis/redis-2.2.11/src/solarisfixes.h +22 -0
  242. data/redis/redis-2.2.11/src/sort.c +389 -0
  243. data/redis/redis-2.2.11/src/syncio.c +154 -0
  244. data/redis/redis-2.2.11/src/t_hash.c +476 -0
  245. data/redis/redis-2.2.11/src/t_list.c +986 -0
  246. data/redis/redis-2.2.11/src/t_set.c +610 -0
  247. data/redis/redis-2.2.11/src/t_string.c +438 -0
  248. data/redis/redis-2.2.11/src/t_zset.c +1084 -0
  249. data/redis/redis-2.2.11/src/testhelp.h +54 -0
  250. data/redis/redis-2.2.11/src/util.c +243 -0
  251. data/redis/redis-2.2.11/src/valgrind.sup +5 -0
  252. data/redis/redis-2.2.11/src/version.h +1 -0
  253. data/redis/redis-2.2.11/src/vm.c +1149 -0
  254. data/redis/redis-2.2.11/src/ziplist.c +1323 -0
  255. data/redis/redis-2.2.11/src/ziplist.h +15 -0
  256. data/redis/redis-2.2.11/src/zipmap.c +455 -0
  257. data/redis/redis-2.2.11/src/zipmap.h +48 -0
  258. data/redis/redis-2.2.11/src/zmalloc.c +278 -0
  259. data/redis/redis-2.2.11/src/zmalloc.h +47 -0
  260. data/redis/redis-2.2.11/tests/assets/default.conf +308 -0
  261. data/redis/redis-2.2.11/tests/integration/aof.tcl +104 -0
  262. data/redis/redis-2.2.11/tests/integration/redis-cli.tcl +208 -0
  263. data/redis/redis-2.2.11/tests/integration/replication.tcl +98 -0
  264. data/redis/redis-2.2.11/tests/support/redis.tcl +241 -0
  265. data/redis/redis-2.2.11/tests/support/server.tcl +294 -0
  266. data/redis/redis-2.2.11/tests/support/test.tcl +190 -0
  267. data/redis/redis-2.2.11/tests/support/tmpfile.tcl +15 -0
  268. data/redis/redis-2.2.11/tests/support/util.tcl +296 -0
  269. data/redis/redis-2.2.11/tests/test_helper.tcl +221 -0
  270. data/redis/redis-2.2.11/tests/unit/auth.tcl +15 -0
  271. data/redis/redis-2.2.11/tests/unit/basic.tcl +616 -0
  272. data/redis/redis-2.2.11/tests/unit/cas.tcl +135 -0
  273. data/redis/redis-2.2.11/tests/unit/expire.tcl +74 -0
  274. data/redis/redis-2.2.11/tests/unit/other.tcl +240 -0
  275. data/redis/redis-2.2.11/tests/unit/printver.tcl +6 -0
  276. data/redis/redis-2.2.11/tests/unit/protocol.tcl +62 -0
  277. data/redis/redis-2.2.11/tests/unit/pubsub.tcl +195 -0
  278. data/redis/redis-2.2.11/tests/unit/quit.tcl +40 -0
  279. data/redis/redis-2.2.11/tests/unit/sort.tcl +189 -0
  280. data/redis/redis-2.2.11/tests/unit/type/hash.tcl +300 -0
  281. data/redis/redis-2.2.11/tests/unit/type/list.tcl +819 -0
  282. data/redis/redis-2.2.11/tests/unit/type/set.tcl +334 -0
  283. data/redis/redis-2.2.11/tests/unit/type/zset.tcl +587 -0
  284. data/redis/redis-2.2.11/utils/build-static-symbols.tcl +22 -0
  285. data/redis/redis-2.2.11/utils/generate-command-help.rb +112 -0
  286. data/redis/redis-2.2.11/utils/mktarball.sh +13 -0
  287. data/redis/redis-2.2.11/utils/redis-copy.rb +78 -0
  288. data/redis/redis-2.2.11/utils/redis-sha1.rb +52 -0
  289. data/redis/redis-2.2.11/utils/redis_init_script +42 -0
  290. metadata +362 -0
@@ -0,0 +1,627 @@
1
+ #include "redis.h"
2
+
3
+ /*-----------------------------------------------------------------------------
4
+ * Config file parsing
5
+ *----------------------------------------------------------------------------*/
6
+
7
+ int yesnotoi(char *s) {
8
+ if (!strcasecmp(s,"yes")) return 1;
9
+ else if (!strcasecmp(s,"no")) return 0;
10
+ else return -1;
11
+ }
12
+
13
+ void appendServerSaveParams(time_t seconds, int changes) {
14
+ server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1));
15
+ server.saveparams[server.saveparamslen].seconds = seconds;
16
+ server.saveparams[server.saveparamslen].changes = changes;
17
+ server.saveparamslen++;
18
+ }
19
+
20
+ void resetServerSaveParams() {
21
+ zfree(server.saveparams);
22
+ server.saveparams = NULL;
23
+ server.saveparamslen = 0;
24
+ }
25
+
26
+ /* I agree, this is a very rudimental way to load a configuration...
27
+ will improve later if the config gets more complex */
28
+ void loadServerConfig(char *filename) {
29
+ FILE *fp;
30
+ char buf[REDIS_CONFIGLINE_MAX+1], *err = NULL;
31
+ int linenum = 0;
32
+ sds line = NULL;
33
+
34
+ if (filename[0] == '-' && filename[1] == '\0')
35
+ fp = stdin;
36
+ else {
37
+ if ((fp = fopen(filename,"r")) == NULL) {
38
+ redisLog(REDIS_WARNING, "Fatal error, can't open config file '%s'", filename);
39
+ exit(1);
40
+ }
41
+ }
42
+
43
+ while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
44
+ sds *argv;
45
+ int argc, j;
46
+
47
+ linenum++;
48
+ line = sdsnew(buf);
49
+ line = sdstrim(line," \t\r\n");
50
+
51
+ /* Skip comments and blank lines*/
52
+ if (line[0] == '#' || line[0] == '\0') {
53
+ sdsfree(line);
54
+ continue;
55
+ }
56
+
57
+ /* Split into arguments */
58
+ argv = sdssplitargs(line,&argc);
59
+ sdstolower(argv[0]);
60
+
61
+ /* Execute config directives */
62
+ if (!strcasecmp(argv[0],"timeout") && argc == 2) {
63
+ server.maxidletime = atoi(argv[1]);
64
+ if (server.maxidletime < 0) {
65
+ err = "Invalid timeout value"; goto loaderr;
66
+ }
67
+ } else if (!strcasecmp(argv[0],"port") && argc == 2) {
68
+ server.port = atoi(argv[1]);
69
+ if (server.port < 0 || server.port > 65535) {
70
+ err = "Invalid port"; goto loaderr;
71
+ }
72
+ } else if (!strcasecmp(argv[0],"bind") && argc == 2) {
73
+ server.bindaddr = zstrdup(argv[1]);
74
+ } else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) {
75
+ server.unixsocket = zstrdup(argv[1]);
76
+ } else if (!strcasecmp(argv[0],"save") && argc == 3) {
77
+ int seconds = atoi(argv[1]);
78
+ int changes = atoi(argv[2]);
79
+ if (seconds < 1 || changes < 0) {
80
+ err = "Invalid save parameters"; goto loaderr;
81
+ }
82
+ appendServerSaveParams(seconds,changes);
83
+ } else if (!strcasecmp(argv[0],"dir") && argc == 2) {
84
+ if (chdir(argv[1]) == -1) {
85
+ redisLog(REDIS_WARNING,"Can't chdir to '%s': %s",
86
+ argv[1], strerror(errno));
87
+ exit(1);
88
+ }
89
+ } else if (!strcasecmp(argv[0],"loglevel") && argc == 2) {
90
+ if (!strcasecmp(argv[1],"debug")) server.verbosity = REDIS_DEBUG;
91
+ else if (!strcasecmp(argv[1],"verbose")) server.verbosity = REDIS_VERBOSE;
92
+ else if (!strcasecmp(argv[1],"notice")) server.verbosity = REDIS_NOTICE;
93
+ else if (!strcasecmp(argv[1],"warning")) server.verbosity = REDIS_WARNING;
94
+ else {
95
+ err = "Invalid log level. Must be one of debug, notice, warning";
96
+ goto loaderr;
97
+ }
98
+ } else if (!strcasecmp(argv[0],"logfile") && argc == 2) {
99
+ FILE *logfp;
100
+
101
+ server.logfile = zstrdup(argv[1]);
102
+ if (!strcasecmp(server.logfile,"stdout")) {
103
+ zfree(server.logfile);
104
+ server.logfile = NULL;
105
+ }
106
+ if (server.logfile) {
107
+ /* Test if we are able to open the file. The server will not
108
+ * be able to abort just for this problem later... */
109
+ logfp = fopen(server.logfile,"a");
110
+ if (logfp == NULL) {
111
+ err = sdscatprintf(sdsempty(),
112
+ "Can't open the log file: %s", strerror(errno));
113
+ goto loaderr;
114
+ }
115
+ fclose(logfp);
116
+ }
117
+ } else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
118
+ if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
119
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
120
+ }
121
+ } else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
122
+ if (server.syslog_ident) zfree(server.syslog_ident);
123
+ server.syslog_ident = zstrdup(argv[1]);
124
+ } else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
125
+ struct {
126
+ const char *name;
127
+ const int value;
128
+ } validSyslogFacilities[] = {
129
+ {"user", LOG_USER},
130
+ {"local0", LOG_LOCAL0},
131
+ {"local1", LOG_LOCAL1},
132
+ {"local2", LOG_LOCAL2},
133
+ {"local3", LOG_LOCAL3},
134
+ {"local4", LOG_LOCAL4},
135
+ {"local5", LOG_LOCAL5},
136
+ {"local6", LOG_LOCAL6},
137
+ {"local7", LOG_LOCAL7},
138
+ {NULL, 0}
139
+ };
140
+ int i;
141
+
142
+ for (i = 0; validSyslogFacilities[i].name; i++) {
143
+ if (!strcasecmp(validSyslogFacilities[i].name, argv[1])) {
144
+ server.syslog_facility = validSyslogFacilities[i].value;
145
+ break;
146
+ }
147
+ }
148
+
149
+ if (!validSyslogFacilities[i].name) {
150
+ err = "Invalid log facility. Must be one of USER or between LOCAL0-LOCAL7";
151
+ goto loaderr;
152
+ }
153
+ } else if (!strcasecmp(argv[0],"databases") && argc == 2) {
154
+ server.dbnum = atoi(argv[1]);
155
+ if (server.dbnum < 1) {
156
+ err = "Invalid number of databases"; goto loaderr;
157
+ }
158
+ } else if (!strcasecmp(argv[0],"include") && argc == 2) {
159
+ loadServerConfig(argv[1]);
160
+ } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
161
+ server.maxclients = atoi(argv[1]);
162
+ } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
163
+ server.maxmemory = memtoll(argv[1],NULL);
164
+ } else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) {
165
+ if (!strcasecmp(argv[1],"volatile-lru")) {
166
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
167
+ } else if (!strcasecmp(argv[1],"volatile-random")) {
168
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
169
+ } else if (!strcasecmp(argv[1],"volatile-ttl")) {
170
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
171
+ } else if (!strcasecmp(argv[1],"allkeys-lru")) {
172
+ server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
173
+ } else if (!strcasecmp(argv[1],"allkeys-random")) {
174
+ server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
175
+ } else if (!strcasecmp(argv[1],"noeviction")) {
176
+ server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
177
+ } else {
178
+ err = "Invalid maxmemory policy";
179
+ goto loaderr;
180
+ }
181
+ } else if (!strcasecmp(argv[0],"maxmemory-samples") && argc == 2) {
182
+ server.maxmemory_samples = atoi(argv[1]);
183
+ if (server.maxmemory_samples <= 0) {
184
+ err = "maxmemory-samples must be 1 or greater";
185
+ goto loaderr;
186
+ }
187
+ } else if (!strcasecmp(argv[0],"slaveof") && argc == 3) {
188
+ server.masterhost = sdsnew(argv[1]);
189
+ server.masterport = atoi(argv[2]);
190
+ server.replstate = REDIS_REPL_CONNECT;
191
+ } else if (!strcasecmp(argv[0],"masterauth") && argc == 2) {
192
+ server.masterauth = zstrdup(argv[1]);
193
+ } else if (!strcasecmp(argv[0],"slave-serve-stale-data") && argc == 2) {
194
+ if ((server.repl_serve_stale_data = yesnotoi(argv[1])) == -1) {
195
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
196
+ }
197
+ } else if (!strcasecmp(argv[0],"glueoutputbuf")) {
198
+ redisLog(REDIS_WARNING, "Deprecated configuration directive: \"%s\"", argv[0]);
199
+ } else if (!strcasecmp(argv[0],"rdbcompression") && argc == 2) {
200
+ if ((server.rdbcompression = yesnotoi(argv[1])) == -1) {
201
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
202
+ }
203
+ } else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) {
204
+ if ((server.activerehashing = yesnotoi(argv[1])) == -1) {
205
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
206
+ }
207
+ } else if (!strcasecmp(argv[0],"daemonize") && argc == 2) {
208
+ if ((server.daemonize = yesnotoi(argv[1])) == -1) {
209
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
210
+ }
211
+ } else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
212
+ if ((server.appendonly = yesnotoi(argv[1])) == -1) {
213
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
214
+ }
215
+ } else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
216
+ zfree(server.appendfilename);
217
+ server.appendfilename = zstrdup(argv[1]);
218
+ } else if (!strcasecmp(argv[0],"no-appendfsync-on-rewrite")
219
+ && argc == 2) {
220
+ if ((server.no_appendfsync_on_rewrite= yesnotoi(argv[1])) == -1) {
221
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
222
+ }
223
+ } else if (!strcasecmp(argv[0],"appendfsync") && argc == 2) {
224
+ if (!strcasecmp(argv[1],"no")) {
225
+ server.appendfsync = APPENDFSYNC_NO;
226
+ } else if (!strcasecmp(argv[1],"always")) {
227
+ server.appendfsync = APPENDFSYNC_ALWAYS;
228
+ } else if (!strcasecmp(argv[1],"everysec")) {
229
+ server.appendfsync = APPENDFSYNC_EVERYSEC;
230
+ } else {
231
+ err = "argument must be 'no', 'always' or 'everysec'";
232
+ goto loaderr;
233
+ }
234
+ } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
235
+ server.requirepass = zstrdup(argv[1]);
236
+ } else if (!strcasecmp(argv[0],"pidfile") && argc == 2) {
237
+ zfree(server.pidfile);
238
+ server.pidfile = zstrdup(argv[1]);
239
+ } else if (!strcasecmp(argv[0],"dbfilename") && argc == 2) {
240
+ zfree(server.dbfilename);
241
+ server.dbfilename = zstrdup(argv[1]);
242
+ } else if (!strcasecmp(argv[0],"vm-enabled") && argc == 2) {
243
+ if ((server.vm_enabled = yesnotoi(argv[1])) == -1) {
244
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
245
+ }
246
+ } else if (!strcasecmp(argv[0],"vm-swap-file") && argc == 2) {
247
+ zfree(server.vm_swap_file);
248
+ server.vm_swap_file = zstrdup(argv[1]);
249
+ } else if (!strcasecmp(argv[0],"vm-max-memory") && argc == 2) {
250
+ server.vm_max_memory = memtoll(argv[1],NULL);
251
+ } else if (!strcasecmp(argv[0],"vm-page-size") && argc == 2) {
252
+ server.vm_page_size = memtoll(argv[1], NULL);
253
+ } else if (!strcasecmp(argv[0],"vm-pages") && argc == 2) {
254
+ server.vm_pages = memtoll(argv[1], NULL);
255
+ } else if (!strcasecmp(argv[0],"vm-max-threads") && argc == 2) {
256
+ server.vm_max_threads = strtoll(argv[1], NULL, 10);
257
+ } else if (!strcasecmp(argv[0],"hash-max-zipmap-entries") && argc == 2) {
258
+ server.hash_max_zipmap_entries = memtoll(argv[1], NULL);
259
+ } else if (!strcasecmp(argv[0],"hash-max-zipmap-value") && argc == 2) {
260
+ server.hash_max_zipmap_value = memtoll(argv[1], NULL);
261
+ } else if (!strcasecmp(argv[0],"list-max-ziplist-entries") && argc == 2){
262
+ server.list_max_ziplist_entries = memtoll(argv[1], NULL);
263
+ } else if (!strcasecmp(argv[0],"list-max-ziplist-value") && argc == 2) {
264
+ server.list_max_ziplist_value = memtoll(argv[1], NULL);
265
+ } else if (!strcasecmp(argv[0],"set-max-intset-entries") && argc == 2) {
266
+ server.set_max_intset_entries = memtoll(argv[1], NULL);
267
+ } else if (!strcasecmp(argv[0],"rename-command") && argc == 3) {
268
+ struct redisCommand *cmd = lookupCommand(argv[1]);
269
+ int retval;
270
+
271
+ if (!cmd) {
272
+ err = "No such command in rename-command";
273
+ goto loaderr;
274
+ }
275
+
276
+ /* If the target command name is the emtpy string we just
277
+ * remove it from the command table. */
278
+ retval = dictDelete(server.commands, argv[1]);
279
+ redisAssert(retval == DICT_OK);
280
+
281
+ /* Otherwise we re-add the command under a different name. */
282
+ if (sdslen(argv[2]) != 0) {
283
+ sds copy = sdsdup(argv[2]);
284
+
285
+ retval = dictAdd(server.commands, copy, cmd);
286
+ if (retval != DICT_OK) {
287
+ sdsfree(copy);
288
+ err = "Target command name already exists"; goto loaderr;
289
+ }
290
+ }
291
+ } else {
292
+ err = "Bad directive or wrong number of arguments"; goto loaderr;
293
+ }
294
+ for (j = 0; j < argc; j++)
295
+ sdsfree(argv[j]);
296
+ zfree(argv);
297
+ sdsfree(line);
298
+ }
299
+ if (fp != stdin) fclose(fp);
300
+ return;
301
+
302
+ loaderr:
303
+ fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
304
+ fprintf(stderr, "Reading the configuration file, at line %d\n", linenum);
305
+ fprintf(stderr, ">>> '%s'\n", line);
306
+ fprintf(stderr, "%s\n", err);
307
+ exit(1);
308
+ }
309
+
310
+ /*-----------------------------------------------------------------------------
311
+ * CONFIG command for remote configuration
312
+ *----------------------------------------------------------------------------*/
313
+
314
+ void configSetCommand(redisClient *c) {
315
+ robj *o;
316
+ long long ll;
317
+ redisAssert(c->argv[2]->encoding == REDIS_ENCODING_RAW);
318
+ redisAssert(c->argv[3]->encoding == REDIS_ENCODING_RAW);
319
+ o = c->argv[3];
320
+
321
+ if (!strcasecmp(c->argv[2]->ptr,"dbfilename")) {
322
+ zfree(server.dbfilename);
323
+ server.dbfilename = zstrdup(o->ptr);
324
+ } else if (!strcasecmp(c->argv[2]->ptr,"requirepass")) {
325
+ zfree(server.requirepass);
326
+ server.requirepass = zstrdup(o->ptr);
327
+ } else if (!strcasecmp(c->argv[2]->ptr,"masterauth")) {
328
+ zfree(server.masterauth);
329
+ server.masterauth = zstrdup(o->ptr);
330
+ } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory")) {
331
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
332
+ ll < 0) goto badfmt;
333
+ server.maxmemory = ll;
334
+ if (server.maxmemory) freeMemoryIfNeeded();
335
+ } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-policy")) {
336
+ if (!strcasecmp(o->ptr,"volatile-lru")) {
337
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
338
+ } else if (!strcasecmp(o->ptr,"volatile-random")) {
339
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_RANDOM;
340
+ } else if (!strcasecmp(o->ptr,"volatile-ttl")) {
341
+ server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_TTL;
342
+ } else if (!strcasecmp(o->ptr,"allkeys-lru")) {
343
+ server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_LRU;
344
+ } else if (!strcasecmp(o->ptr,"allkeys-random")) {
345
+ server.maxmemory_policy = REDIS_MAXMEMORY_ALLKEYS_RANDOM;
346
+ } else if (!strcasecmp(o->ptr,"noeviction")) {
347
+ server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
348
+ } else {
349
+ goto badfmt;
350
+ }
351
+ } else if (!strcasecmp(c->argv[2]->ptr,"maxmemory-samples")) {
352
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
353
+ ll <= 0) goto badfmt;
354
+ server.maxmemory_samples = ll;
355
+ } else if (!strcasecmp(c->argv[2]->ptr,"timeout")) {
356
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
357
+ ll < 0 || ll > LONG_MAX) goto badfmt;
358
+ server.maxidletime = ll;
359
+ } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) {
360
+ if (!strcasecmp(o->ptr,"no")) {
361
+ server.appendfsync = APPENDFSYNC_NO;
362
+ } else if (!strcasecmp(o->ptr,"everysec")) {
363
+ server.appendfsync = APPENDFSYNC_EVERYSEC;
364
+ } else if (!strcasecmp(o->ptr,"always")) {
365
+ server.appendfsync = APPENDFSYNC_ALWAYS;
366
+ } else {
367
+ goto badfmt;
368
+ }
369
+ } else if (!strcasecmp(c->argv[2]->ptr,"no-appendfsync-on-rewrite")) {
370
+ int yn = yesnotoi(o->ptr);
371
+
372
+ if (yn == -1) goto badfmt;
373
+ server.no_appendfsync_on_rewrite = yn;
374
+ } else if (!strcasecmp(c->argv[2]->ptr,"appendonly")) {
375
+ int old = server.appendonly;
376
+ int new = yesnotoi(o->ptr);
377
+
378
+ if (new == -1) goto badfmt;
379
+ if (old != new) {
380
+ if (new == 0) {
381
+ stopAppendOnly();
382
+ } else {
383
+ if (startAppendOnly() == REDIS_ERR) {
384
+ addReplyError(c,
385
+ "Unable to turn on AOF. Check server logs.");
386
+ return;
387
+ }
388
+ }
389
+ }
390
+ } else if (!strcasecmp(c->argv[2]->ptr,"save")) {
391
+ int vlen, j;
392
+ sds *v = sdssplitlen(o->ptr,sdslen(o->ptr)," ",1,&vlen);
393
+
394
+ /* Perform sanity check before setting the new config:
395
+ * - Even number of args
396
+ * - Seconds >= 1, changes >= 0 */
397
+ if (vlen & 1) {
398
+ sdsfreesplitres(v,vlen);
399
+ goto badfmt;
400
+ }
401
+ for (j = 0; j < vlen; j++) {
402
+ char *eptr;
403
+ long val;
404
+
405
+ val = strtoll(v[j], &eptr, 10);
406
+ if (eptr[0] != '\0' ||
407
+ ((j & 1) == 0 && val < 1) ||
408
+ ((j & 1) == 1 && val < 0)) {
409
+ sdsfreesplitres(v,vlen);
410
+ goto badfmt;
411
+ }
412
+ }
413
+ /* Finally set the new config */
414
+ resetServerSaveParams();
415
+ for (j = 0; j < vlen; j += 2) {
416
+ time_t seconds;
417
+ int changes;
418
+
419
+ seconds = strtoll(v[j],NULL,10);
420
+ changes = strtoll(v[j+1],NULL,10);
421
+ appendServerSaveParams(seconds, changes);
422
+ }
423
+ sdsfreesplitres(v,vlen);
424
+ } else if (!strcasecmp(c->argv[2]->ptr,"slave-serve-stale-data")) {
425
+ int yn = yesnotoi(o->ptr);
426
+
427
+ if (yn == -1) goto badfmt;
428
+ server.repl_serve_stale_data = yn;
429
+ } else if (!strcasecmp(c->argv[2]->ptr,"dir")) {
430
+ if (chdir((char*)o->ptr) == -1) {
431
+ addReplyErrorFormat(c,"Changing directory: %s", strerror(errno));
432
+ return;
433
+ }
434
+ } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-entries")) {
435
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
436
+ server.hash_max_zipmap_entries = ll;
437
+ } else if (!strcasecmp(c->argv[2]->ptr,"hash-max-zipmap-value")) {
438
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
439
+ server.hash_max_zipmap_value = ll;
440
+ } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-entries")) {
441
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
442
+ server.list_max_ziplist_entries = ll;
443
+ } else if (!strcasecmp(c->argv[2]->ptr,"list-max-ziplist-value")) {
444
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
445
+ server.list_max_ziplist_value = ll;
446
+ } else if (!strcasecmp(c->argv[2]->ptr,"set-max-intset-entries")) {
447
+ if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
448
+ server.set_max_intset_entries = ll;
449
+ } else {
450
+ addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
451
+ (char*)c->argv[2]->ptr);
452
+ return;
453
+ }
454
+ addReply(c,shared.ok);
455
+ return;
456
+
457
+ badfmt: /* Bad format errors */
458
+ addReplyErrorFormat(c,"Invalid argument '%s' for CONFIG SET '%s'",
459
+ (char*)o->ptr,
460
+ (char*)c->argv[2]->ptr);
461
+ }
462
+
463
+ void configGetCommand(redisClient *c) {
464
+ robj *o = c->argv[2];
465
+ void *replylen = addDeferredMultiBulkLength(c);
466
+ char *pattern = o->ptr;
467
+ char buf[128];
468
+ int matches = 0;
469
+ redisAssert(o->encoding == REDIS_ENCODING_RAW);
470
+
471
+ if (stringmatch(pattern,"dir",0)) {
472
+ char buf[1024];
473
+
474
+ addReplyBulkCString(c,"dir");
475
+ if (getcwd(buf,sizeof(buf)) == NULL) {
476
+ buf[0] = '\0';
477
+ } else {
478
+ addReplyBulkCString(c,buf);
479
+ }
480
+ matches++;
481
+ }
482
+ if (stringmatch(pattern,"dbfilename",0)) {
483
+ addReplyBulkCString(c,"dbfilename");
484
+ addReplyBulkCString(c,server.dbfilename);
485
+ matches++;
486
+ }
487
+ if (stringmatch(pattern,"requirepass",0)) {
488
+ addReplyBulkCString(c,"requirepass");
489
+ addReplyBulkCString(c,server.requirepass);
490
+ matches++;
491
+ }
492
+ if (stringmatch(pattern,"masterauth",0)) {
493
+ addReplyBulkCString(c,"masterauth");
494
+ addReplyBulkCString(c,server.masterauth);
495
+ matches++;
496
+ }
497
+ if (stringmatch(pattern,"maxmemory",0)) {
498
+ ll2string(buf,sizeof(buf),server.maxmemory);
499
+ addReplyBulkCString(c,"maxmemory");
500
+ addReplyBulkCString(c,buf);
501
+ matches++;
502
+ }
503
+ if (stringmatch(pattern,"maxmemory-policy",0)) {
504
+ char *s;
505
+
506
+ switch(server.maxmemory_policy) {
507
+ case REDIS_MAXMEMORY_VOLATILE_LRU: s = "volatile-lru"; break;
508
+ case REDIS_MAXMEMORY_VOLATILE_TTL: s = "volatile-ttl"; break;
509
+ case REDIS_MAXMEMORY_VOLATILE_RANDOM: s = "volatile-random"; break;
510
+ case REDIS_MAXMEMORY_ALLKEYS_LRU: s = "allkeys-lru"; break;
511
+ case REDIS_MAXMEMORY_ALLKEYS_RANDOM: s = "allkeys-random"; break;
512
+ case REDIS_MAXMEMORY_NO_EVICTION: s = "noeviction"; break;
513
+ default: s = "unknown"; break; /* too harmless to panic */
514
+ }
515
+ addReplyBulkCString(c,"maxmemory-policy");
516
+ addReplyBulkCString(c,s);
517
+ matches++;
518
+ }
519
+ if (stringmatch(pattern,"maxmemory-samples",0)) {
520
+ ll2string(buf,sizeof(buf),server.maxmemory_samples);
521
+ addReplyBulkCString(c,"maxmemory-samples");
522
+ addReplyBulkCString(c,buf);
523
+ matches++;
524
+ }
525
+ if (stringmatch(pattern,"timeout",0)) {
526
+ ll2string(buf,sizeof(buf),server.maxidletime);
527
+ addReplyBulkCString(c,"timeout");
528
+ addReplyBulkCString(c,buf);
529
+ matches++;
530
+ }
531
+ if (stringmatch(pattern,"appendonly",0)) {
532
+ addReplyBulkCString(c,"appendonly");
533
+ addReplyBulkCString(c,server.appendonly ? "yes" : "no");
534
+ matches++;
535
+ }
536
+ if (stringmatch(pattern,"no-appendfsync-on-rewrite",0)) {
537
+ addReplyBulkCString(c,"no-appendfsync-on-rewrite");
538
+ addReplyBulkCString(c,server.no_appendfsync_on_rewrite ? "yes" : "no");
539
+ matches++;
540
+ }
541
+ if (stringmatch(pattern,"appendfsync",0)) {
542
+ char *policy;
543
+
544
+ switch(server.appendfsync) {
545
+ case APPENDFSYNC_NO: policy = "no"; break;
546
+ case APPENDFSYNC_EVERYSEC: policy = "everysec"; break;
547
+ case APPENDFSYNC_ALWAYS: policy = "always"; break;
548
+ default: policy = "unknown"; break; /* too harmless to panic */
549
+ }
550
+ addReplyBulkCString(c,"appendfsync");
551
+ addReplyBulkCString(c,policy);
552
+ matches++;
553
+ }
554
+ if (stringmatch(pattern,"save",0)) {
555
+ sds buf = sdsempty();
556
+ int j;
557
+
558
+ for (j = 0; j < server.saveparamslen; j++) {
559
+ buf = sdscatprintf(buf,"%ld %d",
560
+ server.saveparams[j].seconds,
561
+ server.saveparams[j].changes);
562
+ if (j != server.saveparamslen-1)
563
+ buf = sdscatlen(buf," ",1);
564
+ }
565
+ addReplyBulkCString(c,"save");
566
+ addReplyBulkCString(c,buf);
567
+ sdsfree(buf);
568
+ matches++;
569
+ }
570
+ if (stringmatch(pattern,"slave-serve-stale-data",0)) {
571
+ addReplyBulkCString(c,"slave-serve-stale-data");
572
+ addReplyBulkCString(c,server.repl_serve_stale_data ? "yes" : "no");
573
+ matches++;
574
+ }
575
+ if (stringmatch(pattern,"hash-max-zipmap-entries",0)) {
576
+ addReplyBulkCString(c,"hash-max-zipmap-entries");
577
+ addReplyBulkLongLong(c,server.hash_max_zipmap_entries);
578
+ matches++;
579
+ }
580
+ if (stringmatch(pattern,"hash-max-zipmap-value",0)) {
581
+ addReplyBulkCString(c,"hash-max-zipmap-value");
582
+ addReplyBulkLongLong(c,server.hash_max_zipmap_value);
583
+ matches++;
584
+ }
585
+ if (stringmatch(pattern,"list-max-ziplist-entries",0)) {
586
+ addReplyBulkCString(c,"list-max-ziplist-entries");
587
+ addReplyBulkLongLong(c,server.list_max_ziplist_entries);
588
+ matches++;
589
+ }
590
+ if (stringmatch(pattern,"list-max-ziplist-value",0)) {
591
+ addReplyBulkCString(c,"list-max-ziplist-value");
592
+ addReplyBulkLongLong(c,server.list_max_ziplist_value);
593
+ matches++;
594
+ }
595
+ if (stringmatch(pattern,"set-max-intset-entries",0)) {
596
+ addReplyBulkCString(c,"set-max-intset-entries");
597
+ addReplyBulkLongLong(c,server.set_max_intset_entries);
598
+ matches++;
599
+ }
600
+ setDeferredMultiBulkLength(c,replylen,matches*2);
601
+ }
602
+
603
+ void configCommand(redisClient *c) {
604
+ if (!strcasecmp(c->argv[1]->ptr,"set")) {
605
+ if (c->argc != 4) goto badarity;
606
+ configSetCommand(c);
607
+ } else if (!strcasecmp(c->argv[1]->ptr,"get")) {
608
+ if (c->argc != 3) goto badarity;
609
+ configGetCommand(c);
610
+ } else if (!strcasecmp(c->argv[1]->ptr,"resetstat")) {
611
+ if (c->argc != 2) goto badarity;
612
+ server.stat_keyspace_hits = 0;
613
+ server.stat_keyspace_misses = 0;
614
+ server.stat_numcommands = 0;
615
+ server.stat_numconnections = 0;
616
+ server.stat_expiredkeys = 0;
617
+ addReply(c,shared.ok);
618
+ } else {
619
+ addReplyError(c,
620
+ "CONFIG subcommand must be one of GET, SET, RESETSTAT");
621
+ }
622
+ return;
623
+
624
+ badarity:
625
+ addReplyErrorFormat(c,"Wrong number of arguments for CONFIG %s",
626
+ (char*) c->argv[1]->ptr);
627
+ }