Commit | Line | Data |
---|---|---|
5c3f75ec | 1 | /* -*-c-*- |
5c3f75ec | 2 | * |
3 | * Catcrypt common stuff | |
4 | * | |
5 | * (c) 2004 Straylight/Edgeware | |
6 | */ | |
7 | ||
45c0fd36 | 8 | /*----- Licensing notice --------------------------------------------------* |
5c3f75ec | 9 | * |
10 | * This file is part of Catacomb. | |
11 | * | |
12 | * Catacomb is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
45c0fd36 | 16 | * |
5c3f75ec | 17 | * Catacomb is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
45c0fd36 | 21 | * |
5c3f75ec | 22 | * You should have received a copy of the GNU Library General Public |
23 | * License along with Catacomb; if not, write to the Free | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
28 | #ifndef CATACOMB_CC_H | |
29 | #define CATACOMB_CC_H | |
30 | ||
31 | #ifdef __cplusplus | |
32 | extern "C" { | |
33 | #endif | |
34 | ||
35 | /*----- Header files ------------------------------------------------------*/ | |
36 | ||
cd6eca43 MW |
37 | #if _FILE_OFFSET_BITS != 64 |
38 | # error "Must set _FILE_OFFSET_BITS to 64." | |
39 | #endif | |
40 | ||
5c3f75ec | 41 | #include <stdio.h> |
c65df279 | 42 | #include <string.h> |
cd6eca43 | 43 | #include <time.h> |
5c3f75ec | 44 | |
f5e91c02 MW |
45 | #include <sys/types.h> |
46 | #include <sys/stat.h> | |
47 | ||
5c3f75ec | 48 | #include <mLib/dstr.h> |
49 | ||
66ff643c MW |
50 | #include "buf.h" |
51 | #include "ct.h" | |
5c3f75ec | 52 | #include "key.h" |
53 | #include "gcipher.h" | |
54 | #include "ghash.h" | |
55 | #include "gmac.h" | |
56 | ||
a1e745ad | 57 | /*----- Cryptographic object tables ---------------------------------------*/ |
cd6eca43 | 58 | |
66ff643c MW |
59 | typedef struct bulk { |
60 | const struct bulkops *ops; | |
61 | } bulk; | |
62 | ||
63 | typedef struct bulkops { | |
64 | bulk *(*init)(key */*k*/, const char */*calg*/, const char */*halg*/); | |
65 | int (*setup)(bulk */*b*/, gcipher */*cx*/); | |
66 | size_t (*overhead)(bulk */*b*/); | |
67 | const char *(*doit)(bulk */*b*/, uint32 /*seq*/, buf */*bb*/, | |
68 | const void */*p*/, size_t /*sz*/); | |
69 | void (*destroy)(bulk */*b*/); | |
70 | } bulkops; | |
71 | ||
72 | struct bulktab { | |
73 | const char *name; | |
74 | const bulkops *encops; | |
75 | const bulkops *decops; | |
76 | }; | |
77 | ||
78 | extern const struct bulktab bulktab[]; | |
79 | ||
5c3f75ec | 80 | /* --- Key encapsulation --- */ |
81 | ||
82 | typedef struct kem { | |
83 | const struct kemops *ops; | |
84 | key_packdef *kp; | |
85 | void *kd; | |
66ff643c MW |
86 | const gchash *hc; |
87 | const gccipher *cxc; | |
88 | gcipher *cx; | |
5c3f75ec | 89 | } kem; |
90 | ||
91 | typedef struct kemops { | |
92 | const key_fetchdef *kf; /* Key fetching structure */ | |
93 | size_t kdsz; /* Size of the key-data structure */ | |
94 | kem *(*init)(key */*k*/, void */*kd*/); | |
95 | int (*doit)(kem */*k*/, dstr */*d*/, ghash */*h*/); | |
96 | const char *(*check)(kem */*k*/); | |
97 | void (*destroy)(kem */*k*/); | |
98 | } kemops; | |
99 | ||
c65df279 | 100 | struct kemtab { |
101 | const char *name; | |
102 | const kemops *encops; | |
103 | const kemops *decops; | |
104 | }; | |
105 | ||
106 | extern const struct kemtab kemtab[]; | |
107 | ||
5c3f75ec | 108 | /* --- @getkem@ --- * |
109 | * | |
110 | * Arguments: @key *k@ = the key to load | |
111 | * @const char *app@ = application name | |
112 | * @int wantpriv@ = nonzero if we want to decrypt | |
66ff643c | 113 | * @bulk **bc@ = bulk crypto context to set up |
5c3f75ec | 114 | * |
115 | * Returns: A key-encapsulating thing. | |
116 | * | |
117 | * Use: Loads a key. | |
118 | */ | |
119 | ||
66ff643c MW |
120 | extern kem *getkem(key */*k*/, const char */*app*/, int /*wantpriv*/, |
121 | bulk **/*bc*/); | |
5c3f75ec | 122 | |
123 | /* --- @setupkem@ --- * | |
124 | * | |
125 | * Arguments: @kem *k@ = key-encapsulation thing | |
126 | * @dstr *d@ = key-encapsulation data | |
66ff643c | 127 | * @bulk *bc@ = bulk crypto context to set up |
5c3f75ec | 128 | * |
129 | * Returns: Zero for success, nonzero on faliure. | |
130 | * | |
131 | * Use: Initializes all the various symmetric things from a KEM. | |
132 | */ | |
133 | ||
66ff643c | 134 | extern int setupkem(kem */*k*/, dstr */*d*/, bulk */*bc*/); |
5c3f75ec | 135 | |
136 | /* --- @freekem@ --- * | |
137 | * | |
138 | * Arguments: @kem *k@ = key-encapsulation thing | |
139 | * | |
140 | * Returns: --- | |
141 | * | |
142 | * Use: Frees up a key-encapsulation thing. | |
143 | */ | |
144 | ||
145 | extern void freekem(kem */*k*/); | |
146 | ||
a1e745ad MW |
147 | /* --- Signing --- */ |
148 | ||
149 | typedef struct sig { | |
150 | const struct sigops *ops; | |
151 | key_packdef *kp; | |
152 | void *kd; | |
153 | const gchash *ch; | |
154 | ghash *h; | |
155 | } sig; | |
156 | ||
157 | typedef struct sigops { | |
158 | const key_fetchdef *kf; /* Key fetching structure */ | |
159 | size_t kdsz; /* Size of the key-data structure */ | |
160 | sig *(*init)(key */*k*/, void */*kd*/, const gchash */*hc*/); | |
161 | int (*doit)(sig */*s*/, dstr */*d*/); | |
162 | const char *(*check)(sig */*s*/); | |
163 | void (*destroy)(sig */*s*/); | |
164 | } sigops; | |
165 | ||
166 | struct sigtab { | |
167 | const char *name; | |
168 | const sigops *signops; | |
169 | const sigops *verifyops; | |
170 | const gchash *ch; | |
171 | }; | |
172 | ||
173 | extern const struct sigtab sigtab[]; | |
174 | ||
5c3f75ec | 175 | /* --- @getsig@ --- * |
176 | * | |
177 | * Arguments: @key *k@ = the key to load | |
178 | * @const char *app@ = application name | |
179 | * @int wantpriv@ = nonzero if we want to sign | |
180 | * | |
181 | * Returns: A signature-making thing. | |
182 | * | |
183 | * Use: Loads a key and starts hashing. | |
184 | */ | |
185 | ||
186 | extern sig *getsig(key */*k*/, const char */*app*/, int /*wantpriv*/); | |
187 | ||
188 | /* --- @freesig@ --- * | |
189 | * | |
190 | * Arguments: @sig *s@ = signature-making thing | |
191 | * | |
192 | * Returns: --- | |
193 | * | |
194 | * Use: Frees up a signature-making thing | |
195 | */ | |
196 | ||
197 | extern void freesig(sig */*s*/); | |
198 | ||
a1e745ad MW |
199 | /*----- File encodings ----------------------------------------------------*/ |
200 | ||
201 | /* --- Data encoding --- */ | |
202 | ||
203 | typedef struct enc { | |
204 | const struct encops *ops; | |
205 | FILE *fp; | |
206 | } enc; | |
207 | ||
208 | typedef struct encops { | |
209 | const char *name; | |
210 | const char *rmode, *wmode; | |
211 | int nraw, ncook; | |
212 | enc *(*initenc)(FILE */*fp*/, const char */*msg*/); | |
213 | enc *(*initdec)(FILE */*fp*/, | |
214 | int (*/*func*/)(const char *, void *), void */*p*/); | |
215 | int (*read)(enc */*e*/, void */*p*/, size_t /*sz*/); | |
216 | int (*write)(enc */*e*/, const void */*p*/, size_t /*sz*/); | |
217 | int (*encdone)(enc */*e*/); | |
218 | int (*decdone)(enc */*e*/); | |
219 | void (*destroy)(enc */*e*/); | |
220 | } encops; | |
221 | ||
222 | extern const encops enctab[]; | |
223 | ||
5c3f75ec | 224 | /* --- @getenc@ --- * |
225 | * | |
226 | * Arguments: @const char *enc@ = name of wanted encoding | |
227 | * | |
228 | * Returns: Pointer to encoder operations. | |
229 | * | |
230 | * Use: Finds a named encoder or decoder. | |
231 | */ | |
232 | ||
233 | extern const encops *getenc(const char */*enc*/); | |
234 | ||
fa54fe1e | 235 | /* --- @checkbdry@ --- * |
236 | * | |
237 | * Arguments: @const char *b@ = boundary string found | |
238 | * @void *p@ = boundary string wanted | |
239 | * | |
240 | * Returns: Nonzero if the boundary string is the one we wanted. | |
241 | * | |
242 | * Use: Pass as @func@ to @initdec@ if you just want a simple life. | |
243 | */ | |
244 | ||
245 | extern int checkbdry(const char */*b*/, void */*p*/); | |
246 | ||
5c3f75ec | 247 | /* --- @initenc@ --- * |
248 | * | |
249 | * Arguments: @const encops *eo@ = operations (from @getenc@) | |
250 | * @FILE *fp@ = file handle to attach | |
251 | * @const char *msg@ = banner message | |
5c3f75ec | 252 | * |
253 | * Returns: The encoder object. | |
254 | * | |
255 | * Use: Initializes an encoder. | |
256 | */ | |
257 | ||
fa54fe1e | 258 | extern enc *initenc(const encops */*eo*/, FILE */*fp*/, const char */*msg*/); |
259 | ||
260 | /* --- @initdec@ --- * | |
261 | * | |
262 | * Arguments: @const encops *eo@ = operations (from @getenc@) | |
263 | * @FILE *fp@ = file handle to attach | |
264 | * @int (*func)(const char *, void *)@ = banner check function | |
265 | * @void *p@ = argument for @func@ | |
266 | * | |
267 | * Returns: The encoder object. | |
268 | * | |
269 | * Use: Initializes an encoder. | |
270 | */ | |
271 | ||
272 | extern enc *initdec(const encops */*eo*/, FILE */*fp*/, | |
273 | int (*/*func*/)(const char *, void *), void */*p*/); | |
5c3f75ec | 274 | |
275 | /* --- @freeenc@ --- * | |
276 | * | |
277 | * Arguments: @enc *e@ = encoder object | |
278 | * | |
279 | * Returns: --- | |
280 | * | |
281 | * Use: Frees an encoder object. | |
282 | */ | |
283 | ||
284 | extern void freeenc(enc */*e*/); | |
285 | ||
fa54fe1e | 286 | /* --- @cmd_encode@, @cmd_decode@ --- */ |
287 | ||
288 | #define CMD_ENCODE { \ | |
289 | "encode", cmd_encode, \ | |
cd6eca43 | 290 | "encode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]", \ |
fa54fe1e | 291 | "\ |
292 | Options:\n\ | |
293 | \n\ | |
294 | -f, --format=FORMAT Encode to FORMAT.\n\ | |
295 | -b, --boundary=LABEL PEM boundary is LABEL.\n\ | |
296 | -o, --output=FILE Write output to FILE.\n\ | |
cd6eca43 | 297 | -p, --progress Show progress on large files.\n\ |
fa54fe1e | 298 | " } |
299 | ||
300 | #define CMD_DECODE { \ | |
301 | "decode", cmd_decode, \ | |
cd6eca43 | 302 | "decode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]", \ |
fa54fe1e | 303 | "\ |
304 | Options:\n\ | |
305 | \n\ | |
306 | -f, --format=FORMAT Decode from FORMAT.\n\ | |
307 | -b, --boundary=LABEL PEM boundary is LABEL.\n\ | |
308 | -o, --output=FILE Write output to FILE.\n\ | |
cd6eca43 | 309 | -p, --progress Show progress on large files.\n\ |
fa54fe1e | 310 | " } |
311 | ||
312 | extern int cmd_encode(int /*argc*/, char */*argv*/[]); | |
313 | extern int cmd_decode(int /*argc*/, char */*argv*/[]); | |
314 | ||
18b3351a MW |
315 | /*----- Hash encoding functions -------------------------------------------*/ |
316 | ||
317 | /* --- Table --- */ | |
318 | ||
319 | #define ENCODINGS(_) \ | |
320 | _(HEX, hex) \ | |
321 | _(BASE64, base64) \ | |
322 | _(BASE32, base32) | |
323 | ||
324 | enum { | |
325 | #define ENUM(tag, name) ENC_##tag, | |
326 | ENCODINGS(ENUM) | |
327 | #undef ENUM | |
328 | ENC_LIMIT | |
329 | }; | |
330 | ||
331 | typedef struct encodeops { | |
332 | const char *name; | |
333 | void (*put)(const octet *, size_t, FILE *); | |
334 | size_t (*get)(const char *, octet *, size_t, char **); | |
335 | } encodeops; | |
336 | ||
337 | extern const encodeops encodingtab[]; | |
338 | ||
339 | /* --- @getencoding@ --- * | |
340 | * | |
341 | * Arguments: @const char *ename@ = encoding name | |
342 | * | |
343 | * Returns: Pointer to encoding table entry, or null. | |
344 | * | |
345 | * Use: Finds an encoding entry given its name. | |
346 | */ | |
347 | ||
348 | extern const encodeops *getencoding(const char */*ename*/); | |
349 | ||
350 | /*----- File hashing ------------------------------------------------------*/ | |
351 | ||
07290a45 MW |
352 | typedef struct fhashstate { |
353 | const gchash *gch; | |
354 | unsigned f; | |
f5e91c02 | 355 | struct fhent *ents; |
07290a45 MW |
356 | } fhashstate; |
357 | ||
358 | #define FHF_BINARY 0x100u | |
359 | #define FHF_PROGRESS 0x200u | |
f5e91c02 | 360 | #define FHF_JUNK 0x400u |
07290a45 MW |
361 | |
362 | #define FHF_MASK 0xff00u | |
363 | ||
f377eee1 MW |
364 | /* --- @gethash@ --- * |
365 | * | |
366 | * Arguments: @const char *name@ = pointer to name string | |
367 | * | |
368 | * Returns: Pointer to appropriate hash class. | |
369 | * | |
370 | * Use: Chooses a hash function by name. | |
371 | */ | |
372 | ||
373 | extern const gchash *gethash(const char */*name*/); | |
374 | ||
f5e91c02 MW |
375 | /* --- @describefile@ --- * |
376 | * | |
377 | * Arguments: @const struct stat *st@ = pointer to file state | |
378 | * | |
379 | * Returns: A snappy one-word description of the file. | |
380 | */ | |
381 | ||
382 | extern const char *describefile(const struct stat */*st*/); | |
383 | ||
07290a45 MW |
384 | /* --- @fhash_init@ ---* |
385 | * | |
386 | * Arguments: @fhashstate *fh@ = pointer to fhash state to initialize | |
387 | * @const gchash *gch@ = hash class to set | |
388 | * @unsigned f@ initial flags to set | |
389 | * | |
390 | * Returns: --- | |
391 | * | |
392 | * Use: Initializes an @fhashstate@ structure. | |
393 | */ | |
394 | ||
395 | extern void fhash_init(fhashstate */*fh*/, | |
396 | const gchash */*gch*/, unsigned /*f*/); | |
397 | ||
398 | /* --- @fhash_free@ --- * | |
399 | * | |
400 | * Arguments: @fhashstate *fh@ = pointer to fhash state to free | |
401 | * | |
402 | * Returns: --- | |
403 | * | |
404 | * Use: Frees an fhash state. | |
405 | */ | |
406 | ||
407 | extern void fhash_free(fhashstate */*fh*/); | |
408 | ||
18b3351a MW |
409 | /* --- @fhash@ --- * |
410 | * | |
07290a45 | 411 | * Arguments: @fhashstate *fh@ = pointer to fhash state |
18b3351a MW |
412 | * @const char *file@ = file name to be hashed (null for stdin) |
413 | * @void *buf@ = pointer to hash output buffer | |
414 | * | |
415 | * Returns: Zero if it worked, nonzero on error. | |
416 | * | |
417 | * Use: Hashes a file. | |
418 | */ | |
419 | ||
07290a45 | 420 | extern int fhash(fhashstate */*fh*/, const char */*file*/, void */*buf*/); |
18b3351a | 421 | |
f5e91c02 MW |
422 | /* --- @fhash_junk@ --- * |
423 | * | |
424 | * Arguments: @fhashstate *fh@ = pointer to fhash state | |
425 | * @void (*func)(const char *, const struct stat *, void *)@ | |
426 | * @void *p@ = pointer to pass to function | |
427 | * | |
428 | * Returns: Positive if any junk was found, negative on error, zero if | |
429 | * everything was fine. | |
430 | * | |
431 | * Use: Reports junk files in any directories covered by the hash | |
432 | * state. | |
433 | */ | |
434 | ||
435 | extern int fhash_junk(fhashstate */*fh*/, | |
436 | int (*/*func*/)(const char *, | |
437 | const struct stat *, | |
438 | void *), | |
439 | void */*p*/); | |
440 | ||
f377eee1 MW |
441 | /* --- @hfparse@ --- * |
442 | * | |
443 | * Arguments: @hfpctx *hfp@ = pointer to the context structure | |
444 | * | |
445 | * Returns: A code indicating what happened. | |
446 | * | |
447 | * Use: Parses a line from the input file. | |
448 | */ | |
449 | ||
450 | enum { /* Meaning and members set */ | |
451 | HF_FILE, /* File hash: @dline@ and @hbuf@ */ | |
452 | HF_ENC, /* Encoding: @ee@ */ | |
453 | HF_HASH, /* Hash function: @gch@ */ | |
454 | HF_ESC, /* Name escape: @f@ */ | |
455 | HF_EOF, /* End of file */ | |
456 | HF_BAD /* Unrecognized line */ | |
457 | }; | |
458 | ||
459 | typedef struct hfpctx { | |
460 | unsigned f; /* Flags to read */ | |
461 | #define HFF_ESCAPE 1u /* File names are escaped */ | |
462 | FILE *fp; /* Input file to read */ | |
463 | dstr *dline; /* Line contents, corrupted */ | |
464 | const gchash *gch; /* Hash function to use */ | |
465 | const encodeops *ee; /* Encoding to apply to hashes */ | |
466 | dstr *dfile; /* File name for @HF_FILE@ lines */ | |
467 | octet *hbuf; /* Output buffer for hash data */ | |
468 | } hfpctx; | |
469 | ||
470 | extern int hfparse(hfpctx */*hfp*/); | |
471 | ||
18b3351a MW |
472 | /*----- String I/O --------------------------------------------------------*/ |
473 | ||
474 | #define GSF_RAW 4096u | |
475 | #define GSF_FILE 0u | |
476 | #define GSF_STRING 8192u | |
477 | ||
478 | #define GSF_MASK 61440u | |
479 | ||
480 | /* --- @getstring@ --- * | |
481 | * | |
482 | * Arguments: @void *in@ = input source | |
483 | * @dstr *d@ = destination string | |
484 | * @unsigned f@ = input flags | |
485 | * | |
486 | * Returns: Zero if OK, nonzero on end-of-file. | |
487 | * | |
488 | * Use: Reads a filename (or something similar) from a stream. | |
489 | */ | |
490 | ||
491 | extern int getstring(void */*in*/, dstr */*d*/, unsigned /*f*/); | |
492 | ||
493 | /* --- @putstring@ --- * | |
494 | * | |
495 | * Arguments: @FILE *fp@ = stream to write on | |
496 | * @const char *p@ = pointer to text | |
497 | * @unsigned f@ = output flags | |
498 | * | |
499 | * Returns: --- | |
500 | * | |
501 | * Use: Emits a string to a stream. | |
502 | */ | |
503 | ||
504 | extern void putstring(FILE */*fp*/, const char */*p*/, unsigned /*f*/); | |
505 | ||
a1e745ad MW |
506 | /*----- Lists of things ---------------------------------------------------*/ |
507 | ||
c65df279 | 508 | /* --- @LIST(STRING, FP, END-TEST, NAME-EXPR)@ --- * |
509 | * | |
510 | * Produce list of things. Requires @i@ and @w@ variables in scope. | |
511 | * END-TEST and NAME-EXPR are in terms of @i@. | |
512 | */ | |
513 | ||
514 | #define LIST(what, fp, end, name) do { \ | |
515 | fputs(what ":\n ", fp); \ | |
516 | w = 2; \ | |
517 | for (i = 0; end; i++) { \ | |
518 | if (w == 2) \ | |
519 | w += strlen(name); \ | |
520 | else { \ | |
521 | if (strlen(name) + w > 76) { \ | |
522 | fputs("\n ", fp); \ | |
523 | w = 2 + strlen(name); \ | |
524 | } else { \ | |
525 | fputc(' ', fp); \ | |
526 | w += strlen(name) + 1; \ | |
527 | } \ | |
528 | } \ | |
529 | fputs(name, fp); \ | |
530 | } \ | |
531 | fputc('\n', fp); \ | |
532 | } while (0) | |
533 | ||
534 | #define STDLISTS(LI) \ | |
535 | LI("Hash functions", hash, \ | |
536 | ghashtab[i], ghashtab[i]->name) \ | |
537 | LI("Encryption schemes", enc, \ | |
538 | gciphertab[i], gciphertab[i]->name) \ | |
539 | LI("Message authentication schemes", mac, \ | |
540 | gmactab[i], gmactab[i]->name) \ | |
541 | LI("Elliptic curves", ec, \ | |
542 | ectab[i].name, ectab[i].name) \ | |
543 | LI("Diffie-Hellman groups", dh, \ | |
544 | ptab[i].name, ptab[i].name) | |
545 | ||
546 | #define LIDECL(text, tag, test, name) \ | |
547 | static void show_##tag(void); | |
548 | ||
549 | #define LIDEF(text, tag, test, name) \ | |
550 | static void show_##tag(void) \ | |
551 | { \ | |
552 | unsigned i, w; \ | |
553 | LIST(text, stdout, test, name); \ | |
554 | } | |
555 | ||
556 | #define LIENT(text, tag, test, name) \ | |
557 | { #tag, show_##tag }, | |
558 | ||
559 | struct listent { | |
560 | const char *name; | |
561 | void (*list)(void); | |
562 | }; | |
563 | ||
564 | #define MAKELISTTAB(listtab, LISTS) \ | |
565 | LISTS(LIDECL) \ | |
566 | static const struct listent listtab[] = { \ | |
567 | LISTS(LIENT) \ | |
568 | { 0, 0 } \ | |
569 | }; \ | |
570 | LISTS(LIDEF) | |
571 | ||
572 | extern int displaylists(const struct listent */*listtab*/, | |
573 | char *const /*argv*/[]); | |
574 | ||
cd6eca43 MW |
575 | /*----- Progress indicators -----------------------------------------------*/ |
576 | ||
a1e745ad MW |
577 | typedef struct fprogress { |
578 | const char *bp; | |
579 | off_t o, sz, olast; | |
580 | time_t start, last; | |
581 | char name[24]; | |
582 | } fprogress; | |
583 | ||
cd6eca43 MW |
584 | /* --- @fprogress_init@ --- * |
585 | * | |
586 | * Arguments: @fprogress *f@ = progress context to be initialized | |
587 | * @const char *name@ = file name string to show | |
588 | * @FILE *fp@ = file we're reading from | |
589 | * | |
590 | * Returns: Zero on success, nonzero if the file's state is now broken. | |
591 | * | |
592 | * Use: Initializes a progress context. Nothing is actually | |
593 | * displayed yet. | |
594 | */ | |
595 | ||
596 | extern int fprogress_init(fprogress */*f*/, | |
597 | const char */*name*/, FILE */*fp*/); | |
598 | ||
599 | /* --- @fprogress_update@ --- * | |
600 | * | |
601 | * Arguments: @fprogress *f@ = progress context | |
602 | * @size_t n@ = how much progress has been made | |
603 | * | |
604 | * Returns: --- | |
605 | * | |
606 | * Use: Maybe updates the display to show that some progress has been | |
607 | * made. | |
608 | */ | |
609 | ||
610 | extern void fprogress_update(fprogress */*f*/, size_t /*n*/); | |
611 | ||
612 | /* --- @fprogress_clear@ --- * | |
613 | * | |
614 | * Arguments: @fprogress *f@ = progress context | |
615 | * | |
616 | * Returns: --- | |
617 | * | |
618 | * Use: Clears the progress display from the screen. | |
619 | */ | |
620 | ||
621 | extern void fprogress_clear(fprogress */*f*/); | |
622 | ||
623 | /* --- @fprogress_done@ --- * | |
624 | * | |
625 | * Arguments: @fprogress *f@ = progress context | |
626 | * | |
627 | * Returns: --- | |
628 | * | |
629 | * Use: Clear up the progress context and removes any display. | |
630 | */ | |
631 | ||
632 | extern void fprogress_done(fprogress */*f*/); | |
633 | ||
a1e745ad MW |
634 | /*----- Subcommand dispatch -----------------------------------------------*/ |
635 | ||
636 | typedef struct cmd { | |
637 | const char *name; | |
638 | int (*cmd)(int /*argc*/, char */*argv*/[]); | |
639 | const char *usage; | |
640 | const char *help; | |
641 | } cmd; | |
642 | ||
643 | extern void version(FILE */*fp*/); | |
644 | extern void help_global(FILE */*fp*/); | |
645 | ||
646 | /* --- @findcmd@ --- * | |
647 | * | |
648 | * Arguments: @const cmd *cmds@ = pointer to command table | |
649 | * @const char *name@ = a command name | |
650 | * | |
651 | * Returns: Pointer to the command structure. | |
652 | * | |
653 | * Use: Looks up a command by name. If the command isn't found, an | |
654 | * error is reported and the program is terminated. | |
655 | */ | |
656 | ||
657 | const cmd *findcmd(const cmd */*cmds*/, const char */*name*/); | |
658 | ||
659 | /* --- @sc_help@ --- * | |
660 | * | |
661 | * Arguments: @const cmd *cmds@ = pointer to command table | |
662 | * @FILE *fp@ = output file handle | |
663 | * @char *const *argv@ = remaining arguments | |
664 | * | |
665 | * Returns: --- | |
666 | * | |
667 | * Use: Prints a help message, maybe with help about subcommands. | |
668 | */ | |
669 | ||
670 | extern void sc_help(const cmd */*cmds*/, FILE */*fp*/, | |
671 | char *const */*argv*/); | |
672 | ||
5c3f75ec | 673 | /*----- That's all, folks -------------------------------------------------*/ |
674 | ||
675 | #ifdef __cplusplus | |
676 | } | |
677 | #endif | |
678 | ||
679 | #endif |