gnunet-auction-create.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file auction/gnunet-auction-create.c
  18. * @brief tool to create a new auction
  19. * @author Markus Teich
  20. */
  21. #include "platform.h"
  22. #include <float.h>
  23. #include "gnunet_util_lib.h"
  24. #include <jansson.h>
  25. /* #include "gnunet_auction_service.h" */
  26. #define FIRST_PRICE 0
  27. #define OUTCOME_PRIVATE 0
  28. #define OUTCOME_PUBLIC 1
  29. static int ret; /** Final status code. */
  30. static char *fndesc; /** filename of the item description */
  31. static char *fnprices; /** filename of the price map */
  32. static struct GNUNET_TIME_Relative dround; /** max round duration */
  33. static struct GNUNET_TIME_Relative dstart; /** time until auction starts */
  34. static unsigned int m = FIRST_PRICE; /** auction parameter m */
  35. static int outcome = OUTCOME_PRIVATE; /** outcome */
  36. static int interactive; /** keep running in foreground */
  37. /**
  38. * Main function that will be run by the scheduler.
  39. *
  40. * @param cls closure
  41. * @param args remaining command-line arguments
  42. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  43. * @param cfg configuration
  44. */
  45. static void
  46. run(void *cls,
  47. char *const *args,
  48. const char *cfgfile,
  49. const struct GNUNET_CONFIGURATION_Handle *cfg)
  50. {
  51. unsigned int i;
  52. double cur, prev = DBL_MAX;
  53. json_t *pmap;
  54. json_t *parray;
  55. json_t *pnode;
  56. json_error_t jerr;
  57. /* cmdline parsing */
  58. if (GNUNET_TIME_UNIT_ZERO.rel_value_us == dstart.rel_value_us)
  59. {
  60. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  61. "required argument --regtime missing or invalid (zero)\n");
  62. goto fail;
  63. }
  64. if (GNUNET_TIME_UNIT_ZERO.rel_value_us == dround.rel_value_us)
  65. {
  66. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  67. "required argument --roundtime missing or invalid (zero)\n");
  68. goto fail;
  69. }
  70. if (!fndesc)
  71. {
  72. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  73. "required argument --description missing\n");
  74. goto fail;
  75. }
  76. if (!fnprices)
  77. {
  78. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  79. "required argument --pricemap missing\n");
  80. goto fail;
  81. }
  82. /* parse and check pricemap validity */
  83. if (!(pmap = json_load_file(fnprices, JSON_DECODE_INT_AS_REAL, &jerr)))
  84. {
  85. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  86. "parsing pricemap json at %d:%d: %s\n",
  87. jerr.line, jerr.column, jerr.text);
  88. goto fail;
  89. }
  90. if (-1 == json_unpack_ex(pmap, &jerr, JSON_VALIDATE_ONLY,
  91. "{s:s, s:[]}", "currency", "prices"))
  92. {
  93. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  94. "validating pricemap: %s\n", jerr.text);
  95. goto fail;
  96. }
  97. if (!(parray = json_object_get(pmap, "prices")) || !json_is_array(parray))
  98. {
  99. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  100. "could not get `prices` array node from pricemap\n");
  101. goto fail;
  102. }
  103. if (0 == json_array_size(parray))
  104. {
  105. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "empty pricemap array\n");
  106. goto fail;
  107. }
  108. json_array_foreach(parray, i, pnode)
  109. {
  110. if (-1 == json_unpack_ex(pnode, &jerr, 0, "F", &cur))
  111. {
  112. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  113. "validating pricearray index %d: %s\n", i, jerr.text);
  114. goto fail;
  115. }
  116. if (prev <= cur)
  117. {
  118. GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
  119. "validating pricearray index %d: "
  120. "prices must be strictly monotonically decreasing\n",
  121. i);
  122. goto fail;
  123. }
  124. prev = cur;
  125. }
  126. return;
  127. fail:
  128. ret = 1;
  129. return;
  130. }
  131. /**
  132. * The main function.
  133. *
  134. * @param argc number of arguments from the command line
  135. * @param argv command line arguments
  136. * @return 0 ok, 1 on error
  137. */
  138. int
  139. main(int argc, char *const *argv)
  140. {
  141. struct GNUNET_GETOPT_CommandLineOption options[] = {
  142. GNUNET_GETOPT_option_filename('d',
  143. "description",
  144. "FILE",
  145. gettext_noop("description of the item to be sold"),
  146. &fndesc),
  147. GNUNET_GETOPT_option_filename('p',
  148. "pricemap",
  149. "FILE",
  150. gettext_noop("mapping of possible prices"),
  151. &fnprices),
  152. GNUNET_GETOPT_option_relative_time('r',
  153. "roundtime",
  154. "DURATION",
  155. gettext_noop("max duration per round"),
  156. &dround),
  157. GNUNET_GETOPT_option_relative_time('s',
  158. "regtime",
  159. "DURATION",
  160. gettext_noop("duration until auction starts"),
  161. &dstart),
  162. GNUNET_GETOPT_option_uint('m',
  163. "m",
  164. "NUMBER",
  165. gettext_noop("number of items to sell\n"
  166. "0 for first price auction\n"
  167. ">0 for vickrey/M+1st price auction"),
  168. &m),
  169. GNUNET_GETOPT_option_flag('u',
  170. "public",
  171. gettext_noop("public auction outcome"),
  172. &outcome),
  173. GNUNET_GETOPT_option_flag('i',
  174. "interactive",
  175. gettext_noop("keep running in foreground until auction completes"),
  176. &interactive),
  177. GNUNET_GETOPT_OPTION_END
  178. };
  179. if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
  180. return 2;
  181. ret = (GNUNET_OK ==
  182. GNUNET_PROGRAM_run(argc, argv,
  183. "gnunet-auction-create",
  184. gettext_noop("create a new auction and "
  185. "start listening for bidders"),
  186. options,
  187. &run,
  188. NULL)) ? ret : 1;
  189. GNUNET_free((void*)argv);
  190. return ret;
  191. }