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