gdp / apps / gdp-create.c @ master
History | View | Annotate | Download (11.4 KB)
1 | c6293003 | Eric Allman | /* vim: set ai sw=4 sts=4 ts=4 : */
|
---|---|---|---|
2 | |||
3 | 055d3009 | Eric Allman | /*
|
4 | ** LOG-CREATE --- create a new log
|
||
5 | **
|
||
6 | ** This is a temporary interface. Ultimately we need a log
|
||
7 | ** creation service that does reasonable log placement rather
|
||
8 | ** than having to name a specific log server.
|
||
9 | **
|
||
10 | ** ----- BEGIN LICENSE BLOCK -----
|
||
11 | ** Applications for the Global Data Plane
|
||
12 | ** From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
|
||
13 | **
|
||
14 | c87dd166 | Eric Allman | ** Copyright (c) 2015-2019, Regents of the University of California.
|
15 | 6bd5476b | Eric Allman | ** All rights reserved.
|
16 | 055d3009 | Eric Allman | **
|
17 | 6bd5476b | Eric Allman | ** Permission is hereby granted, without written agreement and without
|
18 | ** license or royalty fees, to use, copy, modify, and distribute this
|
||
19 | ** software and its documentation for any purpose, provided that the above
|
||
20 | ** copyright notice and the following two paragraphs appear in all copies
|
||
21 | ** of this software.
|
||
22 | 055d3009 | Eric Allman | **
|
23 | 6bd5476b | Eric Allman | ** IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
24 | ** SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
|
||
25 | ** PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||
26 | ** EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
27 | 055d3009 | Eric Allman | **
|
28 | 6bd5476b | Eric Allman | ** REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
29 | 055d3009 | Eric Allman | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
30 | 6bd5476b | Eric Allman | ** FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
|
31 | ** IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
|
||
32 | ** OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
||
33 | ** OR MODIFICATIONS.
|
||
34 | 055d3009 | Eric Allman | ** ----- END LICENSE BLOCK -----
|
35 | */
|
||
36 | |||
37 | c6293003 | Eric Allman | #include <ep/ep.h> |
38 | #include <ep/ep_app.h> |
||
39 | 80da996e | Eric Allman | //#include <ep/ep_crypto.h>
|
40 | c6293003 | Eric Allman | #include <ep/ep_dbg.h> |
41 | 80da996e | Eric Allman | //#include <ep/ep_string.h>
|
42 | c6293003 | Eric Allman | #include <gdp/gdp.h> |
43 | |||
44 | ffa61df3 | Eric Allman | #include <errno.h> |
45 | c6293003 | Eric Allman | #include <string.h> |
46 | #include <sysexits.h> |
||
47 | 1173b91e | Eric Allman | #include <sys/stat.h> |
48 | c6293003 | Eric Allman | |
49 | 8223a9f1 | Eric Allman | |
50 | 298273b2 | Eric Allman | //static EP_DBG Dbg = EP_DBG_INIT("gdp-create", "Create new log");
|
51 | b84971ef | Eric Allman | |
52 | |||
53 | 78dfc436 | Eric Allman | // command line options
|
54 | 80da996e | Eric Allman | #define OPTIONS "b:c:C:D:e:G:h:k:K:qs:SwW:" |
55 | 78dfc436 | Eric Allman | |
56 | c6293003 | Eric Allman | void
|
57 | usage(void)
|
||
58 | { |
||
59 | 2a942e9a | Eric Allman | fprintf(stderr, "Usage: %s [-C creator] [-D dbgspec] [-e key_enc_alg]\n"
|
60 | 64259fd2 | Eric Allman | "\t[-G gdpd_addr] [-q] [-s logd_name] [-S]\n"
|
61 | 80da996e | Eric Allman | "\t[-h] [-k keytype] [-K owner_keyfile] [-w] [-W writer_keyfile]\n"
|
62 | "\t[-b keybits] [-c curve] [<mdid>=<metadata>...] [log_name]\n"
|
||
63 | 2a942e9a | Eric Allman | " -C set name of log creator (owner; for metadata)\n"
|
64 | 84b021ab | Eric Allman | " -D set debugging flags\n"
|
65 | 25e66e4f | Eric Allman | " -e set secret key encryption algorithm\n"
|
66 | 84b021ab | Eric Allman | " -G IP host to contact for GDP router\n"
|
67 | 2a942e9a | Eric Allman | " -q don't give error if log already exists\n"
|
68 | 80da996e | Eric Allman | " -s set creation service name\n"
|
69 | 64259fd2 | Eric Allman | " -S skip the test to see if log already exists (for debugging)\n"
|
70 | 25e66e4f | Eric Allman | " -h set the hash (message digest) algorithm (defaults to sha256)\n"
|
71 | bf192036 | Eric Allman | " -k type of key; valid key types are \"rsa\", \"dsa\", and \"ec\"\n"
|
72 | "\t(defaults to ec); \"none\" turns off key generation\n"
|
||
73 | 80da996e | Eric Allman | " -K use indicated key/place to write secret owner key\n"
|
74 | " -w create separate writer key\n"
|
||
75 | " -W use indicated key/place to write secret writer key\n"
|
||
76 | "\tIf -K or -W specify a directory, a .pem file is written there\n"
|
||
77 | 84b021ab | Eric Allman | "\twith the name of the GCL (defaults to \"KEYS\" or \".\")\n"
|
78 | b0136566 | Eric Allman | " -b set size of key in bits (RSA and DSA only)\n"
|
79 | " -c set curve name (EC only)\n"
|
||
80 | 2a942e9a | Eric Allman | " creator is the id of the creator, formatted as an email address\n"
|
81 | 84b021ab | Eric Allman | " logd_name is the name of the log server to host this log\n"
|
82 | 2a942e9a | Eric Allman | " metadata ids are (by convention) four letters or digits\n"
|
83 | eae1d3ec | Eric Allman | " log_name is the name of the log to create\n",
|
84 | c6293003 | Eric Allman | ep_app_getprogname()); |
85 | exit(EX_USAGE); |
||
86 | } |
||
87 | |||
88 | |||
89 | int
|
||
90 | main(int argc, char **argv) |
||
91 | { |
||
92 | eae1d3ec | Eric Allman | const char *gobxname = NULL; // external name of GCL |
93 | b84971ef | Eric Allman | const char *logdxname = NULL; // external name of log daemon |
94 | 2a942e9a | Eric Allman | const char *cname = NULL; // creator/owner name (for metadata) |
95 | eae1d3ec | Eric Allman | gdp_gin_t *gin = NULL;
|
96 | 80da996e | Eric Allman | gdp_create_info_t *gci = NULL;
|
97 | c6293003 | Eric Allman | int opt;
|
98 | EP_STAT estat; |
||
99 | char *gdpd_addr = NULL; |
||
100 | bool show_usage = false; |
||
101 | 11e67a2d | Eric Allman | bool quiet = false; |
102 | 64259fd2 | Eric Allman | bool skip_existence_test = false; |
103 | ed3149f0 | Eric Allman | const char *dig_alg_name = "def"; |
104 | const char *key_alg_name = "def"; |
||
105 | 80da996e | Eric Allman | int key_bits = 0; |
106 | const char *key_curve = NULL; |
||
107 | const char *owner_keyfile = NULL; |
||
108 | const char *writer_keyfile = NULL; |
||
109 | ed3149f0 | Eric Allman | const char *key_enc_alg_name = "def"; |
110 | 80da996e | Eric Allman | bool separate_writer_key = false; |
111 | const char *phase = NULL; |
||
112 | c6293003 | Eric Allman | |
113 | 78dfc436 | Eric Allman | // quick pass so debugging is on for initialization
|
114 | while ((opt = getopt(argc, argv, OPTIONS)) > 0) |
||
115 | { |
||
116 | if (opt == 'D') |
||
117 | ep_dbg_set(optarg); |
||
118 | } |
||
119 | 6a095f87 | Eric Allman | optind = 1;
|
120 | #if EP_OSCF_NEED_OPTRESET
|
||
121 | optreset = 1;
|
||
122 | #endif
|
||
123 | 78dfc436 | Eric Allman | |
124 | b8591e8b | Eric Allman | // preinit library (must be early due to crypto code in arg processing)
|
125 | a87ede3e | Eric Allman | ep_crypto_init(0);
|
126 | d18b013a | Eric Allman | |
127 | c6293003 | Eric Allman | // collect command-line arguments
|
128 | 78dfc436 | Eric Allman | while ((opt = getopt(argc, argv, OPTIONS)) > 0) |
129 | c6293003 | Eric Allman | { |
130 | switch (opt)
|
||
131 | { |
||
132 | 2a64fc09 | Eric Allman | case 'b': |
133 | 80da996e | Eric Allman | key_bits = atoi(optarg); |
134 | 2a64fc09 | Eric Allman | break;
|
135 | |||
136 | b0136566 | Eric Allman | case 'c': |
137 | 80da996e | Eric Allman | key_curve = optarg; |
138 | b0136566 | Eric Allman | break;
|
139 | |||
140 | 2a942e9a | Eric Allman | case 'C': |
141 | cname = optarg; |
||
142 | break;
|
||
143 | |||
144 | c6293003 | Eric Allman | case 'D': |
145 | 78dfc436 | Eric Allman | // already done
|
146 | c6293003 | Eric Allman | break;
|
147 | |||
148 | d18b013a | Eric Allman | case 'e': |
149 | 80da996e | Eric Allman | if (ep_crypto_keyenc_byname(optarg) < 0) |
150 | d18b013a | Eric Allman | { |
151 | ep_app_error("unknown key encryption algorithm %s", optarg);
|
||
152 | show_usage = true;
|
||
153 | } |
||
154 | 80da996e | Eric Allman | key_enc_alg_name = optarg; |
155 | d18b013a | Eric Allman | break;
|
156 | |||
157 | c6293003 | Eric Allman | case 'G': |
158 | gdpd_addr = optarg; |
||
159 | break;
|
||
160 | |||
161 | 2a64fc09 | Eric Allman | case 'h': |
162 | 80da996e | Eric Allman | if (ep_crypto_md_alg_byname(optarg) < 0) |
163 | e57b2ceb | Eric Allman | { |
164 | 2a64fc09 | Eric Allman | ep_app_error("unknown digest hash algorithm %s", optarg);
|
165 | show_usage = true;
|
||
166 | e57b2ceb | Eric Allman | } |
167 | 80da996e | Eric Allman | dig_alg_name = optarg; |
168 | c6293003 | Eric Allman | break;
|
169 | |||
170 | 2a64fc09 | Eric Allman | case 'k': |
171 | 80da996e | Eric Allman | if (ep_crypto_keytype_byname(optarg) == EP_CRYPTO_KEYTYPE_UNKNOWN)
|
172 | 2a64fc09 | Eric Allman | { |
173 | ep_app_error("unknown key type %s", optarg);
|
||
174 | show_usage = true;
|
||
175 | } |
||
176 | 80da996e | Eric Allman | key_alg_name = optarg; |
177 | 2a64fc09 | Eric Allman | break;
|
178 | |||
179 | bf192036 | Eric Allman | case 'K': |
180 | 80da996e | Eric Allman | owner_keyfile = optarg; |
181 | bf192036 | Eric Allman | break;
|
182 | |||
183 | 11e67a2d | Eric Allman | case 'q': |
184 | quiet = true;
|
||
185 | break;
|
||
186 | |||
187 | b84971ef | Eric Allman | case 's': |
188 | logdxname = optarg; |
||
189 | break;
|
||
190 | |||
191 | 64259fd2 | Eric Allman | case 'S': |
192 | skip_existence_test = true;
|
||
193 | break;
|
||
194 | |||
195 | 80da996e | Eric Allman | case 'w': |
196 | separate_writer_key = true;
|
||
197 | break;
|
||
198 | |||
199 | case 'W': |
||
200 | writer_keyfile = optarg; |
||
201 | separate_writer_key = true;
|
||
202 | break;
|
||
203 | |||
204 | c6293003 | Eric Allman | default:
|
205 | show_usage = true;
|
||
206 | break;
|
||
207 | } |
||
208 | } |
||
209 | argc -= optind; |
||
210 | argv += optind; |
||
211 | |||
212 | b84971ef | Eric Allman | if (show_usage || argc < 0) |
213 | c6293003 | Eric Allman | usage(); |
214 | |||
215 | 80da996e | Eric Allman | // initialize the GDP library
|
216 | phase = "initializing GDP";
|
||
217 | estat = gdp_init(gdpd_addr); |
||
218 | if (!EP_STAT_ISOK(estat))
|
||
219 | goto fail0;
|
||
220 | |||
221 | // allow thread to settle to avoid interspersed debug output
|
||
222 | ep_time_nanosleep(INT64_C(100000000));
|
||
223 | |||
224 | gci = gdp_create_info_new(); |
||
225 | |||
226 | // collect any metadata and external name
|
||
227 | while (argc > 0) |
||
228 | c6293003 | Eric Allman | { |
229 | 80da996e | Eric Allman | char *p;
|
230 | if ((p = strchr(argv[0], '=')) != NULL) |
||
231 | { |
||
232 | gdp_md_id_t mdid = 0;
|
||
233 | int i;
|
||
234 | |||
235 | p++; |
||
236 | for (i = 0; i < 4; i++) |
||
237 | { |
||
238 | if (argv[0][i] == '=') |
||
239 | break;
|
||
240 | mdid = (mdid << 8) | (unsigned) argv[0][i]; |
||
241 | } |
||
242 | feb6c5a2 | Eric Allman | if (argv[0][i] != '=') |
243 | ep_app_warn("metadata id %.*s truncated to 4 characters",
|
||
244 | (int) (p - argv[0] - 1), argv[0]); |
||
245 | c6293003 | Eric Allman | |
246 | 80da996e | Eric Allman | gdp_create_info_add_metadata(gci, mdid, strlen(p), p); |
247 | } |
||
248 | else if (gobxname == NULL) |
||
249 | c6293003 | Eric Allman | { |
250 | 80da996e | Eric Allman | gobxname = *argv; |
251 | } |
||
252 | else
|
||
253 | { |
||
254 | usage(); |
||
255 | c6293003 | Eric Allman | } |
256 | |||
257 | argc--; |
||
258 | argv++; |
||
259 | } |
||
260 | |||
261 | // name is optional ; if omitted one will be created
|
||
262 | if (argc-- > 0) |
||
263 | eae1d3ec | Eric Allman | gobxname = *argv++; |
264 | c39a16b1 | Eric Allman | if (gobxname != NULL && gobxname[0] == '0') |
265 | gobxname = NULL;
|
||
266 | c6293003 | Eric Allman | |
267 | if (show_usage || argc > 0) |
||
268 | usage(); |
||
269 | |||
270 | eae1d3ec | Eric Allman | if (gobxname != NULL) |
271 | 11e67a2d | Eric Allman | { |
272 | c39a16b1 | Eric Allman | // check validity of the name
|
273 | gdp_name_t gobiname; |
||
274 | if (EP_STAT_ISOK(gdp_internal_name(gobxname, gobiname)))
|
||
275 | { |
||
276 | // this is a valid base64-encooded log name: not appropriate
|
||
277 | estat = GDP_STAT_GDP_NAME_INVALID; |
||
278 | if (!quiet)
|
||
279 | { |
||
280 | ep_app_error("Cannot choose internal GDPname (%s)",
|
||
281 | gobxname); |
||
282 | exit(EX_CANTCREAT); |
||
283 | } |
||
284 | } |
||
285 | 64259fd2 | Eric Allman | if (!skip_existence_test)
|
286 | 11e67a2d | Eric Allman | { |
287 | c39a16b1 | Eric Allman | /*
|
288 | ** If the external name is already known in the
|
||
289 | ** Human-Oriented Name to GDPname directory, OR if the
|
||
290 | ** hashed (old-style) internal name can be found,
|
||
291 | ** then there is a conflict.
|
||
292 | */
|
||
293 | |||
294 | 80da996e | Eric Allman | gin = NULL;
|
295 | c39a16b1 | Eric Allman | estat = gdp_name_parse(gobxname, gobiname, NULL);
|
296 | if (EP_STAT_ISWARN(estat))
|
||
297 | 64259fd2 | Eric Allman | { |
298 | c39a16b1 | Eric Allman | // iname used is the SHA256 of the xname
|
299 | estat = gdp_gin_open(gobiname, GDP_MODE_RO, NULL, &gin);
|
||
300 | } |
||
301 | if (EP_STAT_ISOK(estat))
|
||
302 | { |
||
303 | // oops, we shouldn't be able to parse or open it
|
||
304 | 80da996e | Eric Allman | if (gin != NULL) |
305 | (void) gdp_gin_close(gin);
|
||
306 | 64259fd2 | Eric Allman | if (!quiet)
|
307 | eae1d3ec | Eric Allman | ep_app_error("Cannot create %s: already exists", gobxname);
|
308 | 64259fd2 | Eric Allman | exit(EX_CANTCREAT); |
309 | } |
||
310 | 11e67a2d | Eric Allman | } |
311 | } |
||
312 | |||
313 | 034d97fd | Eric Allman | /**************************************************************
|
314 | ** Set up other automatic metadata
|
||
315 | */
|
||
316 | |||
317 | 80da996e | Eric Allman | if (cname != NULL) |
318 | 034d97fd | Eric Allman | { |
319 | 80da996e | Eric Allman | phase = "setting creator";
|
320 | estat = gdp_create_info_set_creator(gci, cname, NULL);
|
||
321 | EP_STAT_CHECK(estat, goto fail1);
|
||
322 | 034d97fd | Eric Allman | } |
323 | |||
324 | 80da996e | Eric Allman | if (logdxname != NULL) |
325 | 2a942e9a | Eric Allman | { |
326 | 80da996e | Eric Allman | phase = "setting creation service";
|
327 | estat = gdp_create_info_set_creation_service(gci, logdxname); |
||
328 | c39a16b1 | Eric Allman | // OK if iname is hash of xname, which presents as a warning
|
329 | if (EP_STAT_ISFAIL(estat))
|
||
330 | goto fail1;
|
||
331 | 2a942e9a | Eric Allman | } |
332 | 034d97fd | Eric Allman | |
333 | 80da996e | Eric Allman | if (owner_keyfile != NULL) |
334 | d18b013a | Eric Allman | { |
335 | 1173b91e | Eric Allman | // could be an existing file or a directory
|
336 | 80da996e | Eric Allman | phase = "setting owner key";
|
337 | 1173b91e | Eric Allman | struct stat st;
|
338 | int istat = stat(owner_keyfile, &st);
|
||
339 | |||
340 | if (istat < 0) |
||
341 | { |
||
342 | // non-existent file: error
|
||
343 | ep_app_error("%s must exist", owner_keyfile);
|
||
344 | estat = ep_stat_from_errno(ENOENT); |
||
345 | } |
||
346 | else if ((st.st_mode & S_IFMT) == S_IFDIR) |
||
347 | { |
||
348 | // arrange for key to be written to this directory
|
||
349 | phase = "creating owner key";
|
||
350 | ep_adm_setparam("swarm.gdp.crypto.key.dir", owner_keyfile);
|
||
351 | estat = gdp_create_info_new_owner_key(gci, dig_alg_name, |
||
352 | key_alg_name, key_bits, key_curve, |
||
353 | key_enc_alg_name); |
||
354 | } |
||
355 | else
|
||
356 | { |
||
357 | // existing key file --- use it instead of creating new key
|
||
358 | EP_CRYPTO_KEY *key = NULL;
|
||
359 | key = ep_crypto_key_read_file(owner_keyfile, |
||
360 | EP_CRYPTO_KEYFORM_UNKNOWN, EP_CRYPTO_F_SECRET); |
||
361 | estat = gdp_create_info_set_owner_key(gci, key, dig_alg_name); |
||
362 | } |
||
363 | d18b013a | Eric Allman | } |
364 | 1173b91e | Eric Allman | else
|
365 | 2a64fc09 | Eric Allman | { |
366 | 80da996e | Eric Allman | phase = "creating owner key";
|
367 | estat = gdp_create_info_new_owner_key(gci, dig_alg_name, key_alg_name, |
||
368 | key_bits, key_curve, key_enc_alg_name); |
||
369 | e57b2ceb | Eric Allman | } |
370 | 80da996e | Eric Allman | EP_STAT_CHECK(estat, goto fail1);
|
371 | e57b2ceb | Eric Allman | |
372 | 80da996e | Eric Allman | if (writer_keyfile != NULL) |
373 | c6293003 | Eric Allman | { |
374 | 80da996e | Eric Allman | phase = "setting writer key";
|
375 | 8e138989 | Eric Allman | EP_CRYPTO_KEY *key; |
376 | key = ep_crypto_key_read_file(writer_keyfile, 0, EP_CRYPTO_F_SECRET);
|
||
377 | 80da996e | Eric Allman | estat = gdp_create_info_set_writer_key(gci, key, dig_alg_name); |
378 | c6293003 | Eric Allman | } |
379 | 80da996e | Eric Allman | else if (separate_writer_key) |
380 | c6293003 | Eric Allman | { |
381 | 80da996e | Eric Allman | phase = "creating writer key";
|
382 | estat = gdp_create_info_new_writer_key(gci, dig_alg_name, key_alg_name, |
||
383 | key_bits, key_curve, key_enc_alg_name); |
||
384 | c6293003 | Eric Allman | } |
385 | 80da996e | Eric Allman | EP_STAT_CHECK(estat, goto fail1);
|
386 | c6293003 | Eric Allman | |
387 | c39a16b1 | Eric Allman | // if the user specified an unqualified name and we have a root name,
|
388 | // use the extended name.
|
||
389 | const char *root = gdp_name_root_get(); |
||
390 | char xnamebuf[GDP_HUMAN_NAME_MAX + 1]; |
||
391 | if (gobxname != NULL && strchr(gobxname, '.') == NULL && root != NULL) |
||
392 | { |
||
393 | snprintf(xnamebuf, sizeof xnamebuf, "%s.%s", root, gobxname); |
||
394 | gobxname = xnamebuf; |
||
395 | } |
||
396 | |||
397 | d18b013a | Eric Allman | /*
|
398 | ** Hello sailor, this is where the actual creation happens
|
||
399 | */
|
||
400 | 034d97fd | Eric Allman | |
401 | 80da996e | Eric Allman | phase = "creating GDP object";
|
402 | estat = gdp_gin_create(gci, gobxname, &gin); |
||
403 | c6293003 | Eric Allman | EP_STAT_CHECK(estat, goto fail1);
|
404 | |||
405 | d18b013a | Eric Allman | // just for a lark, let the user know the (internal) name
|
406 | 11e67a2d | Eric Allman | if (!quiet)
|
407 | d18b013a | Eric Allman | { |
408 | gdp_pname_t pname; |
||
409 | c6293003 | Eric Allman | |
410 | 71f57d41 | Eric Allman | // this output gets parsed by gdp-rest --- don't change it!
|
411 | 80da996e | Eric Allman | printf("Created new GCL %s\n",
|
412 | gdp_printable_name(*gdp_gin_getname(gin), pname)); |
||
413 | c6293003 | Eric Allman | } |
414 | |||
415 | eae1d3ec | Eric Allman | gdp_gin_close(gin); |
416 | 7fcb8dfd | Eric Allman | |
417 | c6293003 | Eric Allman | fail1:
|
418 | 80da996e | Eric Allman | // free creation information
|
419 | gdp_create_info_free(&gci); |
||
420 | |||
421 | fail0:
|
||
422 | if (!EP_STAT_ISOK(estat))
|
||
423 | 1a2e6f40 | Rick Pratt | { |
424 | 80da996e | Eric Allman | char ebuf[100]; |
425 | ep_app_error("Creation failed while %s: %s",
|
||
426 | phase, ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
427 | 1a2e6f40 | Rick Pratt | } |
428 | c6293003 | Eric Allman | |
429 | 2dba893f | Eric Allman | int exitstat;
|
430 | if (EP_STAT_ISOK(estat))
|
||
431 | exitstat = EX_OK; |
||
432 | a4ca7afc | Eric Allman | else if (EP_STAT_IS_SAME(estat, GDP_STAT_NAK_NOROUTE)) |
433 | 2dba893f | Eric Allman | exitstat = EX_NOHOST; |
434 | 4964758b | Eric Allman | else if (EP_STAT_IS_SAME(estat, GDP_STAT_NAK_CONFLICT)) |
435 | exitstat = EX_CANTCREAT; |
||
436 | a4ca7afc | Eric Allman | else if (EP_STAT_ISABORT(estat)) |
437 | 2dba893f | Eric Allman | exitstat = EX_SOFTWARE; |
438 | else
|
||
439 | exitstat = EX_UNAVAILABLE; |
||
440 | |||
441 | c6293003 | Eric Allman | // OK status can have values; hide that from the user
|
442 | if (EP_STAT_ISOK(estat))
|
||
443 | estat = EP_STAT_OK; |
||
444 | 2dba893f | Eric Allman | |
445 | if (!EP_STAT_ISOK(estat))
|
||
446 | 9829d4ae | Eric Allman | ep_app_message(estat, "exiting with status");
|
447 | 2dba893f | Eric Allman | else if (!quiet) |
448 | fprintf(stderr, "Exiting with status OK\n");
|
||
449 | cb98e88e | Eric Allman | |
450 | return exitstat;
|
||
451 | c6293003 | Eric Allman | } |