Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / doc / developer / Libep.dbk @ master

History | View | Annotate | Download (94.7 KB)

1 dc11518f Eric Allman
<?xml version="1.0" encoding="US-ASCII"?>
2 d63b8179 Eric Allman
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
4
<article class="techreport">
5
  <articleinfo>
6
    <title>Notes on "EP" Library</title>
7
8
    <author>
9
      <firstname>Eric</firstname>
10
11
      <surname>Allman</surname>
12
    </author>
13
14
    <copyright>
15 11ef2ab4 Eric Allman
      <year>2008, 2014&ndash;2018 Eric P. Allman. All rights reserved.</year>
16 d63b8179 Eric Allman
    </copyright>
17
18 11ef2ab4 Eric Allman
    <date>2018-08-15</date>
19 d63b8179 Eric Allman
  </articleinfo>
20
21
  <section>
22
    <title>INTRODUCTION</title>
23
24
    <para>This document describes the Enhanced Portability library. This is a
25
    reduced version of Eric's Portability library (designed for sendmail),
26
    removing many things that didn't work out or proved unnecessary, e.g., the
27
    entire I/O subsystem. It was originally intended to be used in sendmail,
28
    so some of the terminology is geared toward the email world; none the
29
    less, it should be generally useful.</para>
30
31 058dfca9 Eric Allman
    <para>Programs using <symbol>libep</symbol> should be able to minimize
32
    <symbol>#ifdef</symbol> since often non-portable functionality is wrapped
33
    in portability routines; for example, BSD-derived systems and
34
    Linux-derived systems differ in how you get the name of the currently
35
    running program. These differences are hidden if the application calls
36
    <function>ep_app_getprogname</function>.</para>
37
38 d63b8179 Eric Allman
    <section>
39
      <title>Design Goals</title>
40
41
      <itemizedlist>
42
        <listitem>
43
          <para>Portable, to the extent possible. Where not possible, there
44
          needs to be a clearly codified way to represent the externally
45
          visible semantic differences.</para>
46
        </listitem>
47
48
        <listitem>
49
          <para>Efficient.</para>
50
        </listitem>
51
52
        <listitem>
53
          <para>Customizable -- try to implement mechanism, not policy.</para>
54
        </listitem>
55
56
        <listitem>
57
          <para>TBD: It should be entirely UTF-8 internally. Any translations
58
          to other character sets should be done on input or output, and then
59
          only as strictly necessary.</para>
60
        </listitem>
61
      </itemizedlist>
62
    </section>
63
64
    <section>
65
      <title>Assumptions</title>
66
67
      <para>Use of this library requires that you have a C compiler that is
68
      compliant with ANSI C as defined by ANSI/ISO 9899-1999. Also requires an
69
      environment that is at least Posix based on Posix.1-2008.</para>
70
    </section>
71
72
    <section>
73
      <title>Conventions</title>
74
75
      <para><itemizedlist>
76
          <listitem>
77
            <para>All externally visible names (i.e., those not declared
78
            "static" in a file) shall be named ep_* (for routine names) or Ep*
79
            (for variable names). In a few cases, the names may begin with
80
            __ep or __Ep; such names would be in the global namespace, but
81 058dfca9 Eric Allman
            would be intended for use internal to the library only. There are
82
            a few cases where "standard" names (such as
83
            <function>strlcpy</function>) are defined if they are not included
84
            in the standard library.</para>
85 d63b8179 Eric Allman
          </listitem>
86
        </itemizedlist></para>
87
    </section>
88
89
    <section>
90
      <title>Terminology</title>
91
92
      <section>
93
        <title>Warning, Error, Severe, Abort</title>
94
95
        <para>These words get used fairly loosely, so they are worth defining.
96
        In the context of libep:</para>
97
98
        <itemizedlist>
99
          <listitem>
100
            <para>Warning means a condition that is expected in normal
101
            operations, but is not the usual case. Reading an end-of-file on a
102
            file might be a warning. Applications need to be aware of these,
103
            but are expected to either ignore them or recover easily. This can
104
            also be used for temporary errors which are likely to recover
105
            after a delay. For example, the inability to open a connection to
106
            a remote server might recover automatically if that server is
107
            re-started. However, this sort of warnings that persist should
108
            turn into permanent errors in a fashion appropriate for the
109
            application.</para>
110
          </listitem>
111
112
          <listitem>
113
            <para>Error means a situation that should not occur, but isn't
114
            terribly unusual. For example, an attempt to open a file that
115
            isn't accessible would be an error. Applications must be aware of
116
            such conditions and handle them gracefully.</para>
117
          </listitem>
118
119
          <listitem>
120
            <para>Severe means a situation that should not occur iand requires
121
            exceptional handling. Severe errors are drastic conditions, but
122
            are not so severe that the application can't take some reasonable
123
            backout action.</para>
124
          </listitem>
125
126
          <listitem>
127
            <para>Abort means a situation so drastic that an application
128
            cannot be expected to make any reasonable recovery. These might
129
            include assertion errors and memory allocation failures during a
130
            critical step (e.g., something where backing out a single thread
131
            won't solve the problem). About the only thing an application can
132
            reasonably do is log an abort error and exit. In particular, an
133
            abort is appropriate when an attempt for an application to recover
134
            is likely to do additional damage. These should be extremely
135
            rare.</para>
136
          </listitem>
137
        </itemizedlist>
138
      </section>
139
    </section>
140
  </section>
141
142
  <section>
143
    <title>GENERAL ISSUES</title>
144
145
    <para>All files using this library must use "<code>#include
146
    &lt;ep/ep.h&gt;</code>".</para>
147
  </section>
148
149
  <section>
150
    <title>STATUS CODES</title>
151
152
    <para>Almost all functions return an <type>EP_STAT</type> value. This is a
153
    short (integer-encoded) status value that gives you a brief idea of how
154
    severe the problem was and some idea of what it was, but not much else.
155
    Think of it as an errno equivalent. Functions returning any status other
156
    than OK are expected to provide some other way of returning detailed
157
    data.</para>
158
159
    <para><type>EP_STAT</type>s are also used as message identifiers for
160
    logging (below).</para>
161
162
    <para>Status codes are defined in
163
    <filename>&lt;ep/ep_stat.h&gt;</filename>.</para>
164
165
    <section>
166
      <title>Severities</title>
167
168
      <para>Severities are:</para>
169
170
      <variablelist termlength="20">
171
        <varlistentry>
172
          <term><errortype>EP_STAT_SEV_OK</errortype></term>
173
174
          <listitem>
175
            <para>Everything is fine. Detail may contain info. For messages,
176
            can be used for debugging.</para>
177
          </listitem>
178
        </varlistentry>
179
180
        <varlistentry>
181
          <term><errortype>EP_STAT_SEV_WARN</errortype></term>
182
183
          <listitem>
184
            <para>The function partially succeeded, but there is something
185
            that the application should be aware of, e.g., an end of file or a
186
            short data read. Alternatively, the functionfailed, but it might
187
            work again on a later try.</para>
188
          </listitem>
189
        </varlistentry>
190
191
        <varlistentry>
192
          <term><errortype>EP_STAT_SEV_ERROR</errortype></term>
193
194
          <listitem>
195
            <para>A normal error status. The call failed.</para>
196
          </listitem>
197
        </varlistentry>
198
199
        <varlistentry>
200
          <term><errortype>EP_STAT_SEV_SEVERE</errortype></term>
201
202
          <listitem>
203
            <para>A severe error status. The call failed, and the caller
204
            should try to back out.</para>
205
          </listitem>
206
        </varlistentry>
207
208
        <varlistentry>
209
          <term><errortype>EP_STAT_SEV_ABORT</errortype></term>
210
211
          <listitem>
212 dc11518f Eric Allman
            <para>A critical error occured &mdash; you should clean up and
213
            exit as soon as possible; the program cannot be expected to
214
            operate correctly.</para>
215 d63b8179 Eric Allman
          </listitem>
216
        </varlistentry>
217
      </variablelist>
218
219
      <para>Some functions for testing values:</para>
220
221
      <variablelist>
222
        <varlistentry>
223
          <term><function>EP_STAT_SEV_ISOK</function>(st)</term>
224
225
          <listitem>
226
            <para>Returns true if this is an
227
            <errortype>EP_STAT_SEV_OK</errortype> status code.</para>
228
          </listitem>
229
        </varlistentry>
230
231
        <varlistentry>
232
          <term><function>EP_STAT_SEV_WARN</function>(st)</term>
233
234
          <listitem>
235
            <para>Returns true if this is an "warning" severity status code:
236
            <errortype>EP_STAT_SEV_WARN</errortype>.</para>
237
          </listitem>
238
        </varlistentry>
239
240
        <varlistentry>
241
          <term><function>EP_STAT_SEV_ISERROR</function>(st)</term>
242
243
          <listitem>
244
            <para>Returns true if this is an "error" severity status code:
245
            <errortype>EP_STAT_SEV_ERROR</errortype></para>
246
          </listitem>
247
        </varlistentry>
248
249
        <varlistentry>
250 1b56a7ee Eric Allman
          <term><function>EP_STAT_SEV_ISFAIL</function>(st)</term>
251 d63b8179 Eric Allman
252
          <listitem>
253 1b56a7ee Eric Allman
            <para>Returns true if this message is a "failure" severity status
254
            code: <errortype>EP_STAT_SEV_ERROR</errortype> or higher.</para>
255 d63b8179 Eric Allman
          </listitem>
256
        </varlistentry>
257
258
        <varlistentry>
259
          <term><function>EP_STAT_SEV_ISSEVERE</function>(st)</term>
260
261
          <listitem>
262
            <para>Returns true if this is an "severe" severity status code:
263
            <errortype>EP_STAT_SEV_SEVERE</errortype></para>
264
          </listitem>
265
        </varlistentry>
266
267
        <varlistentry>
268 1b56a7ee Eric Allman
          <term><function>EP_STAT_SEV_ISSFAIL</function>(st)</term>
269 d63b8179 Eric Allman
270
          <listitem>
271
            <para>Returns true if this message is a "major" severity status
272
            code: <errortype>EP_STAT_SEV_SEVERE</errortype> or higher</para>
273
          </listitem>
274
        </varlistentry>
275
276
        <varlistentry>
277
          <term><function>EP_STAT_SEV_ISABORT</function>(st)</term>
278
279
          <listitem>
280
            <para>Returns true if this is an "abort" severity status code:
281
            <errortype>EP_STAT_SEV_ABORT</errortype></para>
282
          </listitem>
283
        </varlistentry>
284
      </variablelist>
285
    </section>
286
287
    <section>
288
      <title>Status Code Representation</title>
289
290
      <para>Status codes are represented as four-part values: severity,
291
      registry, module, and detail. The severities are described above.
292
      Registries are globally registered by neophilic.com and are defined in
293
      ep_registry.h. There are some registries for general use; in particular,
294
      registry numbers between 0x001 and 0x1FF are available for local
295
      (non-global) registry at the corporate or local level. Modules are
296
      defined by registries, and detail is defined by module. It is
297
      <emphasis>never</emphasis> acceptable to look at detail unless you
298
      recognize the module. (OK, you can print it out for debugging.) Severity
299
      = 3 bits, registry = 13 bits, module = 6 bits, detail = 10 bits.</para>
300
301
      <para>Any severity where the top bit is zero is considered "OK", and the
302
      rest of the word is available to encode a non-negative integer.</para>
303
304
      <para>Status codes are represented as structures to ensure type safety.
305
      Occassionally you might want to convert a status to or from a long
306
      int:</para>
307
308 42d9d20e Eric Allman
      <programlisting>int      EP_STAT_TO_INT(EP_STAT stat)          // convert status to unsigned int
309
EP_STAT  EP_STAT_FROM_INT(unsigned int istat)  // convert unsigned integer to status</programlisting>
310 d63b8179 Eric Allman
311
      <para>The constituent parts of the status code can also be
312
      extracted:</para>
313
314
      <variablelist>
315
        <varlistentry>
316
          <term><function>EP_STAT_SEV</function>(st)</term>
317
318
          <listitem>
319
            <para>Returns the severity part of the status code.</para>
320
          </listitem>
321
        </varlistentry>
322
323
        <varlistentry>
324
          <term><function>EP_STAT_REGISTRY</function>(st)</term>
325
326
          <listitem>
327
            <para>Returns the registry part of the status code.</para>
328
          </listitem>
329
        </varlistentry>
330
331
        <varlistentry>
332
          <term><function>EP_STAT_MODULE</function>(st)</term>
333
334
          <listitem>
335
            <para>Returns the module part of the status code.</para>
336
          </listitem>
337
        </varlistentry>
338
339
        <varlistentry>
340
          <term><function>EP_STAT_DETAIL</function>(st)</term>
341
342
          <listitem>
343
            <para>Returns the detail part of the status code.</para>
344
          </listitem>
345
        </varlistentry>
346
      </variablelist>
347
348
      <para>To compare two statuses for equality, use
349
      <function>EP_STAT_IS_SAME</function>(a, b).</para>
350
351
      <para>As a special case, if the severity is
352
      <errortype>EP_STAT_SEV_OK</errortype> the rest of the word is ignored;
353 42d9d20e Eric Allman
      this can be used to pass small integers (no more than 31 bits) of
354 d63b8179 Eric Allman
      information.</para>
355
    </section>
356 42d9d20e Eric Allman
357
    <section>
358
      <title>Predefined Status Codes</title>
359
360
      <para>All status codes from this library are in the
361
      <constant>EP_REGISTRY_EPLIB</constant> registery. There are several
362
      predefined status codes for generic use, all using module
363
      <constant>EP_STAT_MOD_GENERIC</constant>:</para>
364
365
      <informaltable border="1">
366 11ef2ab4 Eric Allman
        <col width="4*"/>
367 ac90b0f6 Eric Allman
368 11ef2ab4 Eric Allman
        <col width="6*"/>
369 ac90b0f6 Eric Allman
370 42d9d20e Eric Allman
        <tr>
371
          <td>EP_STAT_OK</td>
372
373
          <td>No error (also integer 0)</td>
374
        </tr>
375
376
        <tr>
377
          <td>EP_STAT_WARN</td>
378
379
          <td>Generic warning status</td>
380
        </tr>
381
382
        <tr>
383
          <td>EP_STAT_ERROR</td>
384
385
          <td>Generic error status</td>
386
        </tr>
387
388
        <tr>
389
          <td>EP_STAT_SEVERE</td>
390
391
          <td>Generic severe error status</td>
392
        </tr>
393
394
        <tr>
395
          <td>EP_STAT_ABORT</td>
396
397
          <td>Generic abortive status</td>
398
        </tr>
399
400
        <tr>
401
          <td>EP_STAT_OUT_OF_MEMORY</td>
402
403
          <td>Out of memory</td>
404
        </tr>
405
406
        <tr>
407
          <td>EP_STAT_ARG_OUT_OF_RANGE</td>
408
409
          <td>An argument was out of range</td>
410
        </tr>
411
412
        <tr>
413
          <td>EP_STAT_END_OF_FILE</td>
414
415
          <td>End of input</td>
416
        </tr>
417
418
        <tr>
419
          <td>EP_STAT_TIME_BADFORMAT</td>
420
421
          <td>Couldn't parse a date/time string</td>
422
        </tr>
423 ac90b0f6 Eric Allman
424
        <tr>
425
          <td>EP_STAT_BUF_OVERFLOW</td>
426
427
          <td>Buffer overflow averted</td>
428
        </tr>
429 8d7fc458 Eric Allman
430
        <tr>
431
          <td>EP_STAT_ASSERT_ABORT</td>
432
433
          <td>Assertion failiure: backout now!</td>
434
        </tr>
435 42d9d20e Eric Allman
      </informaltable>
436
437
      <para>There is also a special module
438 ac90b0f6 Eric Allman
      <constant>EP_STAT_MOD_ERRNO</constant> that encodes Posix-style errnos
439
      (i.e., use <function>EP_STAT_DETAIL</function> on codes returned by that
440
      module to get the Posix errno code).</para>
441 42d9d20e Eric Allman
    </section>
442
443
    <section>
444
      <title>Manipulating Status Codes</title>
445
446
      <para>There are several routines to print error codes or create them on
447
      the fly. Note that <function>ep_stat_tostr</function> returns the buffer
448
      itself.</para>
449
450
      <programlisting>// create status code from UNIX errno
451
extern EP_STAT  ep_stat_from_errno(
452
                        int uerrno);
453
454
// return string representation of status
455
char            *ep_stat_tostr(
456
                        EP_STAT estat,
457
                        char *buf,
458
                        size_t bsize);
459
460
// return string representation of severity (in natural language)
461
const char      *ep_stat_sev_tostr(
462
                        int sev);
463
464
// print a status code and abort (never returns)
465
void            ep_stat_abort(
466
                        EP_STAT estat);</programlisting>
467
    </section>
468
469
    <section>
470
      <title>Creating New Status Codes</title>
471
472
      <para>Libraries and applications can create their own specific error
473
      codes. There are four steps to do this:</para>
474
475
      <orderedlist>
476
        <listitem>
477
          <para>Determine the registry. The registry name space is divided as
478
          follows:</para>
479
480
          <informaltable border="1">
481 11ef2ab4 Eric Allman
            <col width="4*"/>
482 ac90b0f6 Eric Allman
483 11ef2ab4 Eric Allman
            <col width="6*"/>
484 ac90b0f6 Eric Allman
485 42d9d20e Eric Allman
            <tr>
486
              <td>0x000 (<constant>EP_REGISTRY_GENERIC</constant>)</td>
487
488
              <td>reserved for generic status codes</td>
489
            </tr>
490
491
            <tr>
492
              <td>0x001 (<constant>EP_REGISTRY_USER</constant>)</td>
493
494
              <td>available for internal use to an application</td>
495
            </tr>
496
497
            <tr>
498
              <td>0x002&ndash;0x07F</td>
499
500
              <td>available for local, unregistered use, such as separate
501
              applications within an application suite</td>
502
            </tr>
503
504
            <tr>
505
              <td>0x080&ndash;0x0FF</td>
506
507
              <td>available for internal corporate registry, but not
508
              registered globally; conflicts may occur between organizations
509
              but not within an organization</td>
510
            </tr>
511
512
            <tr>
513
              <td>0x100 (<constant>EP_REGISTRY_EPLIB</constant>)</td>
514
515
              <td>reserved for libep</td>
516
            </tr>
517
518
            <tr>
519
              <td>0x101&ndash;0x6FF</td>
520
521
              <td>available for centrally managed global registry &mdash;
522
              contact the libep maintainers for an allocation</td>
523
            </tr>
524
525
            <tr>
526
              <td>0x700&ndash;0x7FF</td>
527
528
              <td>reserved</td>
529
            </tr>
530
          </informaltable>
531
        </listitem>
532
533
        <listitem>
534
          <para>Determine the module(s) in which the error code should exist.
535
          These must be unique within a registry and in the range
536
          0x00&ndash;0xFF.</para>
537
        </listitem>
538
539
        <listitem>
540
          <para>Define the error codes you want to use using
541
          <function>EP_STAT_NEW</function>, e.g.,</para>
542
543
          <programlisting>#define FOO_STAT_ELEPHANT    EP_STAT_NEW(ERROR, EP_REGISTRY_FOO, MOD_BAR, 1)
544
#define FOO_STAT_GIRAFFE     EP_STAT_NEW(SEVERE, EP_REGISTRY_FOO, MOD_BAR, 2)</programlisting>
545
        </listitem>
546
547
        <listitem>
548
          <para>(Optional step) Define the strings associated with the error
549
          codes when they are printed. These are done by populating a table
550
          and then calling <function>ep_stat_register_strings</function>. For
551
          example:</para>
552
553
          <programlisting>struct ep_stat_reg_strings  FooStatusCodes[] =
554
{
555
    FOO_STAT_ELEPHANT,    "elephant in the room",        },
556
    FOO_STAT_GIRAFFE,     "too tall",                    },
557
    EP_STAT_OK,           NULL,                          }
558
}
559
560
ep_stat_reg_strings(FooStatusCodes);</programlisting>
561
        </listitem>
562
      </orderedlist>
563
    </section>
564 d63b8179 Eric Allman
  </section>
565
566
  <section>
567
    <title>INITIALIZATION</title>
568
569
    <para>Although libep will generally work without initialization, in some
570
    cases you may need to give it information about your usage. To do this
571
    call <function>ep_lib_init</function>:</para>
572
573
    <programlisting>#include &lt;ep/ep.h&gt;
574
575
EP_STAT
576
ep_lib_init(uint32_t flags)</programlisting>
577
578
    <para>Flags can be:</para>
579
580 42d9d20e Eric Allman
    <informaltable>
581 d63b8179 Eric Allman
      <tgroup cols="2">
582
        <tbody>
583
          <row>
584
            <entry>EP_LIB_USEPTHREADS</entry>
585
586
            <entry>Initialize the thread support</entry>
587
          </row>
588
        </tbody>
589
      </tgroup>
590 42d9d20e Eric Allman
    </informaltable>
591 d63b8179 Eric Allman
  </section>
592
593
  <section>
594
    <title>MEMORY ALLOCATION AND RESOURCE POOLS</title>
595
596
    <section>
597
      <title>Memory</title>
598
599
      <para>Memory support is much like malloc/free, but with some additional
600
      functionality. One crucial difference is that most of these routines do
601
      not return if memory is exhausted; instead they can call a cleanup
602
      routine that might (for example) eliminate some old cache entries, or
603
      pick a "victim" thread to kill and reclaim its memory. If successful
604
      they can continue, otherwise the process is aborted.</para>
605
606
      <programlisting>    #include &lt;ep/ep_mem.h&gt;
607
608
    void *
609
    ep_mem_malloc(size_t nbytes)       // allocate uninitialized memory
610
611
    void *
612
    ep_mem_zalloc(size_t nbytes)       // allocate zeroed memory
613
614
    void *
615
    ep_mem_ralloc(size_t nbytes)       // allocate randomized memory
616
617
    void *
618
    ep_mem_ealloc(size_t nbytes)       // allocate memory, failure OK
619
620
    void *
621
    ep_mem_realloc(size_t nbytes,      // reallocate (extend) memory
622
                void *curmem)
623
624
    void *
625
    ep_mem_falloc(size_t nbytes,       // allocate memory (see flags)
626
                uint32_t flags)
627
628
    void
629
    ep_mem_mfree(void *mem)            // free indicated memory
630
631
    struct ep_malloc_functions
632
    {
633
        void    *(*m_malloc)(size_t);
634
        void    *(*m_realloc)(void*, size_t);
635
        void    *(*m_valloc)(size_t);
636
        void    (*m_free)(void*);
637
    };
638
639
    void
640
    ep_mem_set_malloc_functions(       // set underlying malloc functions
641
                struct ep_malloc_functions *funcs)</programlisting>
642
643
      <para>The <function>ep_mem_malloc</function>,
644
      <function>ep_mem_zalloc</function>, <function>ep_mem_ralloc</function>,
645
      and <function>ep_mem_realloc</function> are all implemented in terms of
646
      <function>ep_mem_falloc</function>, which uses flags to tune the
647
      behavior (see below). The primary interface is
648
      <function>ep_mem_malloc</function>, which returns uninitialized data;
649
      <function>ep_mem_zalloc</function> returns zeroed memory, and
650
      <function>ep_mem_ralloc</function> returns memory that is initialized to
651
      random or some other nonsensical data. The last would probably be used
652
      only for debugging, and can be turned on at runtime using a debug flag
653
      <remark>XXX TBD</remark>.</para>
654
655
      <para>In all allocation schemes, the function returns a pointer to the
656 dc11518f Eric Allman
      allocated data &mdash; they cannot normally return
657
      <constant>NULL</constant> (but see below). If they cannot allocate the
658
      memory, they <remark>do error recovery (XXX describe)</remark>. If
659
      recovery fails, the allocation system will abort the process. However,
660 d63b8179 Eric Allman
      <function>ep_mem_ealloc</function> can return <constant>NULL</constant>
661
      on memory allocation failure, as can <function>ep_mem_falloc</function>
662
      if the <constant>EP_MEM_F_FAILOK</constant> flag bit is set (see
663
      below).</para>
664
665
      <para>Flag bits are as follows:</para>
666
667
      <variablelist>
668
        <varlistentry>
669
          <term><constant>EP_MEM_F_FAILOK</constant></term>
670
671
          <listitem>
672
            <para>Permits the routine to return <constant>NULL</constant> on
673
            failure. This modifies the behavior described above. Note that if
674
            this is set every call to the <function>ep_*malloc</function>
675
            routines may potentially fail.</para>
676
          </listitem>
677
        </varlistentry>
678
679
        <varlistentry>
680
          <term><constant>EP_MEM_F_ZERO</constant></term>
681
682
          <listitem>
683
            <para>Zero any returned memory.</para>
684
          </listitem>
685
        </varlistentry>
686
687
        <varlistentry>
688
          <term><constant>EP_MEM_F_TRASH</constant></term>
689
690
          <listitem>
691
            <para>Randomize any returned memory.</para>
692
          </listitem>
693
        </varlistentry>
694
695
        <varlistentry>
696
          <term><constant>EP_MEM_F_ALIGN</constant></term>
697
698
          <listitem>
699
            <para>The application would prefer that the allocation is
700
            page-aligned. This is not available on all architectures, and
701
            other architectures do it automatically if the allocation is at
702
            least as large as a page.</para>
703
          </listitem>
704
        </varlistentry>
705
706
        <varlistentry>
707
          <term><constant>EP_MEM_F_WAIT</constant></term>
708
709
          <listitem>
710
            <para>If memory is unavailable, try to wait for it to become
711
            available (e.g., because another thread has released memory).
712
            <remark>This is not yet implemented.</remark></para>
713
          </listitem>
714
        </varlistentry>
715
      </variablelist>
716
717
      <para>Specifying <constant>EP_MEM_F_ZERO</constant> and
718
      <constant>EP_MEM_F_TRASH</constant> at the same time is
719
      undefined.</para>
720
721
      <para>Since <function>ep_mem_[mzr]alloc</function> are implemented as
722
      macros, they can't be used as pointers to functions (e.g., for
723
      specifying a memory allocator callback to a third party app). For this
724
      reason, there are also <function>ep_mem_[mzr]alloc_f</function> "real"
725
      functions to be used in this context.</para>
726
727
      <para>Generally, unthreaded code and most application code will probably
728
      be happy with the defaults. Threaded server code (which cannot be
729
      permitted to die) is expected to catch the out of memory condition, do
730
      some recovery operation such as terminating a task, and return
731
      <errorcode>EP_MEM_STAT_TRYAGAIN</errorcode> so the memory allocation can
732
      retry.</para>
733
734
      <para>[[[XXX Document ep_set_malloc_functions XXX]]]</para>
735
    </section>
736
737
    <section>
738
      <title>Resource Pools</title>
739
740
      <para>Resources are allocatable global entities such as memory, file
741
      descriptors, etc. Resources can be collected together into pools and
742
      then freed in one call. Memory is specially handled to allow fast
743
      allocation from a pool --- specifically, a chunk of memory can be
744
      allocated from the heap to a pool and then sub-allocated as needed.
745
      Allocating memory from resource pools is particularly fast for small
746
      allocations. Also, pool allocations that are of a size that is a
747
      multiple of the page size are guaranteed to return a page-aligned
748
      pointer. This is particularly useful to allow the I/O level to implement
749
      zero-copy I/O.</para>
750
751
      <para>The heap used is the one that is current when
752
      <function>ep_rpool_new</function> is invoked.</para>
753
754
      <programlisting>    #include &lt;ep/ep_mem.h&gt;
755
756
    EP_RPOOL *
757
    ep_rpool_new(const char *name,              // for debugging
758
                size_t qsize)                   // min memory allocation quantum
759
760
    EP_STAT
761
    ep_rpool_free(EP_RPOOL *rp)                 // free pool and all resources
762
763
    void *
764
    ep_rpool_malloc(EP_RPOOL *rp,               // the pool to allocate from
765
                size_t nbytes)                  // number of bytes
766
767
    void *
768
    ep_rpool_zalloc(EP_RPOOL *rp,               // the pool to allocate from
769
                size_t nbytes)                  // number of bytes
770
771
    void *
772
    ep_rpool_xalloc(EP_RPOOL *rp,               // the pool to allocate from
773
                size_t nbytes,                  // number of bytes
774
                const char *filename,           // file name (for debugging)
775
                int lineno,                     // line number (for debugging)
776
                uint32_t flags)                 // flag bits (see below)
777
778
    void *
779
    ep_rpool_strdup(EP_RPOOL *rp,               // the pool to allocate from
780
                char *str)                      // the string to save
781
782
    void *
783
    ep_rpool_realloc(EP_RPOOL *rp,              // pool to allocate from
784
                void *old mem,                  // old memory pointer
785
                size_t oldsize,                 // old allocation size
786
                size_t newsize)                 // new allocation size
787
788
    void
789
    ep_rpool_mfree(EP_RPOOL *rp,                // the pool to release to
790
                void *p);                       // the memory
791
792
    void
793
    ep_rpool_mfreeto(EP_RPOOL *rp,              // the pool to release to
794
                void *p);                       // restore up the pool to here
795
796
    EP_STAT
797
    ep_rpool_attach(EP_RPOOL *rp,               // the resource pool
798
                void freefunc(void *arg),       // a function to call on free
799
                void *arg)                      // argument to pass to it</programlisting>
800
801
      <para>The <function>ep_rpool_mfreeto</function>() routine lets you treat
802
      rpool memory like a stack; this call releases everything allocated back
803
      to (and including) the pointer given. If <computeroutput>p ==
804
      NULL</computeroutput>, the entire memory contents of the rpool are
805
      freed, but the rpool itself is still active. Deep care needs to be taken
806
      here: if a subordinate routine is called that allocates memory from the
807
      rpool, you may end up deallocating memory that is still in use.
808
      <remark>Not implemented at this time.</remark></para>
809
810
      <para>The <function>ep_rpool_attach</function>() routine is used to
811
      associate other resources (such as files) with a pool. The corresponding
812
      free functions will be invoked when the pool is freed.</para>
813
814
      <para>In most cases, passing in <parameter>rp</parameter> ==
815
      <constant>NULL</constant> treats the call like the corresponding heap
816
      allocation. In this case the caller is responsible for freeing the
817
      memory. For example,
818
      <function>ep_rpool_malloc</function>(<constant>NULL</constant>,
819
      <varname>nbytes</varname>) is equivalent to
820
      <function>ep_mem_malloc</function>(<varname>nbytes</varname>).</para>
821
822
      <para>The distinction between multiple heaps and resource pools are that
823
      heaps are not intended for application use other than for doing recovery
824
      for out-of-memory conditions. Pools are intended for general use. Pools
825
      are fast at allocation time (since they just grab space from the end of
826
      the pool) and fast at free time (since the entire pool can be
827
      deallocated at once); heaps are comparatively slow.</para>
828
829
      <para>When any memory collections (heaps or pools) are freed, all
830
      objects allocated from that collection are freed (i.e., their
831
      destructors are automatically invoked).</para>
832
    </section>
833
834
    <section>
835
      <title>Opening Memory as a File</title>
836
837
      <programlisting>    FILE *
838 a5a912e2 Eric Allman
    ep_fopen_smem(void *buf,          // block of memory to open
839 d63b8179 Eric Allman
        size_t bsize,                 // size of that memory
840
        const char *mode)             // fopen(3) mode string</programlisting>
841
    </section>
842
  </section>
843
844
  <section>
845
    <title>TIME</title>
846
847
    <para>The ep library has a separate time abstraction. This is for two
848
    reasons: first, it guarantees that the number of seconds since January 1,
849
    1970 will be sufficiently long to last past 2038 (this varies from system
850
    to system), and it includes a "<structfield>tv_accuracy</structfield>"
851
    (type float) to indicate the approximate accuracy of the clock relative to
852
    absolute time. For example, a clock synchronized from a GPS clock might be
853
    accurate within perhaps 100nsec, whereas a standard crystal clock
854
    synchronized once a day might only have an accuracy of a few
855
    seconds.</para>
856
857
    <programlisting>#include &lt;ep/ep_time.h&gt;
858
859
typedef struct
860
{
861
        int64_t     tv_sec;          // seconds since Jan 1, 1970
862
        int32_t     tv_nsec;         // nanoseconds
863
        float       tv_accuracy;     // clock accuracy in seconds
864
} EP_TIME_SPEC;
865
866 65ffb923 Eric Allman
#define EP_TIME_NOTIME      (-INT64_MAX)
867
#define EP_TIME_MAXTIME     (INT64_MAX)
868
869 d63b8179 Eric Allman
EP_STAT
870
ep_time_now(                         // return current time
871
        EP_TIME_SPEC *tv);
872
873
EP_STAT
874
ep_time_deltanow(                    // return time in the future (or past)
875
        uint64_t delta_nanoseconds,
876
        EP_TIME_SPEC *tv);
877
878
void
879
ep_time_add_delta(                   // add a delta to a time (delta may be negative)
880
        EP_TIME_SPEC *delta,
881
        EP_TIME_SPEC *tv);
882
883
bool
884
ep_time_before(                      // determine if A occurred before B
885
        EP_TIME_SPEC *a,
886
        EP_TIME_SPEC *b);
887
888
void
889
ep_time_from_nsec(                   // create a time from a scalar number of nanoseconds
890 65ffb923 Eric Allman
        int64_t nsec,
891
        EP_TIME_SPEC *tv);
892
893
void
894
ep_time_from_sec(                    // create a time from a scalar number of seconds
895
        int64_t sec,
896 d63b8179 Eric Allman
        EP_TIME_SPEC *tv);
897
898
float
899
ep_time_accuracy(void);              // return putative clock accuracy
900
901
void
902
ep_time_setaccuracy(                 // set the clock accuracy (may not be available)
903
        float accuracy);
904
905
void
906
ep_time_format(                      // format a time string into a buffer
907
        EP_TIME_SPEC *tv,
908
        char *buf,
909
        size_t bufsize,
910 034d97fd Eric Allman
        uint32_t flags);
911 d63b8179 Eric Allman
912
void
913
ep_time_print(                       // format a time string to a file
914
        EP_TIME_SPEC *tv,
915
        FILE *fp,
916 034d97fd Eric Allman
        uint32_t flags);
917
918
// values for ep_time_format and ep_time_print flags
919
#define EP_TIME_FMT_DEFAULT     0               // pseudo-flag
920
#define EP_TIME_FMT_HUMAN       0x00000001      // format for humans
921
#define EP_TIME_FMT_NOFUZZ      0x00000002      // suppress accuracy printing
922 d63b8179 Eric Allman
923
EP_STAT
924
ep_time_parse(                       // parse a time string
925
        const char *timestr,
926 d2647d1f Eric Allman
        EP_TIME_SPEC *tv,
927
        uint32_t flags);
928
929
// values for ep_time_parse flags
930
#define EP_TIME_USE_UTC         0x00000000      // assume UTC (default)
931
#define EP_TIME_USE_LOCALTIME   0x00000001      // assume times in local zone
932 d63b8179 Eric Allman
933
EP_STAT
934
ep_time_nanosleep(                   // sleep for the indicated number of nanoseconds
935
        int64_t nanoseconds);
936
937
bool
938 d2647d1f Eric Allman
EP_TIME_IS_VALID(                    // test to see if a timestamp is valid
939 d63b8179 Eric Allman
        EP_TIME_SPEC *tv);
940
941
void
942
EP_TIME_INVALIDATE(                  // invalidate a timestamp
943
        EP_TIME_SPEC *tv);</programlisting>
944
945
    <para>"Human" formatted times are intended to be human readable, and may
946
    use non-ASCII characters. Otherwise the format is intended to be machine
947
    readable, e.g., using <function>ep_time_parse</function>.</para>
948
  </section>
949
950
  <section>
951
    <title>DATA STRUCTURES</title>
952
953
    <section>
954
      <title>Property Lists</title>
955
956
      <para><remark>Not implemented at this time.</remark> A series of
957
      key=value pairs. Used for many things, including configuration files.
958
      For example, looking in the "configuration" property list for
959
      "<varname>mailer.local.timeout.connect</varname>" would return the
960
      connect timeout for the local mailer. <remark>[[How does this deal with
961 dc11518f Eric Allman
      nested defaults &mdash; e.g., looking for timeout.connect if the full
962
      path cannot be found?]]</remark></para>
963 d63b8179 Eric Allman
964
      <programlisting>    EP_PLIST *
965
    ep_plist_new(
966
                const char *name)              // for printing
967
968
    EP_STAT
969
    ep_plist_load(
970
                EP_PLIST *plp,                 // the list to read into
971
                FILE *sp,                      // the stream to load from
972
                const char *prefix)            // prefix added to all properties
973
974
    EP_STAT
975
    ep_plist_set(
976
                EP_PLIST *plp,                 // the plist in which to set
977
                const char *keyname,           // the name of the key to set
978
                const char *value)             // the value to set (will be copied)
979
980
    const char *
981
    ep_plist_get(
982
                EP_PLIST *plp,                 // the plist to search
983
                const char *keyname)           // the name of the key to get
984
985
    void
986
    ep_plist_dump(
987
                EP_PLIST *plp,                 // plist to print
988
                FILE *sp)                      // stream to print to
989
990
    void
991
    ep_plist_free(
992
                EP_PLIST *plp)                 // plist to free</programlisting>
993
994
      <para>A property list can be loaded from an external stream using
995
      <function>ep_plist_load</function>. The syntax of the file is a simple
996
      text file with "key=value" pairs on separate lines, with blank lines and
997
      those with # at the beginning of the line ignored. The values are
998
      strictly strings. <remark>[[Does it make sense to type
999
      them?]]</remark></para>
1000
1001
      <para><remark>[[Note the overlap between plists and the
1002
      <function>ep_adm</function> interface. Does this make
1003
      sense?]]</remark></para>
1004
1005
      <para>Property lists can be printed using
1006
      <function>ep_plist_dump</function>. The output format will be readable
1007
      by <function>ep_plist_load</function>. For the time being,
1008
      <varname>flags</varname> should always be <constant>0</constant>.</para>
1009
1010
      <warning>
1011
        <para>The property list is not guaranteed to be dumped in the same
1012
        order items are inserted.</para>
1013
      </warning>
1014
    </section>
1015
1016
    <section>
1017
      <title>Hashes</title>
1018
1019
      <programlisting>    #include &lt;ep/ep_hash.h&gt;
1020
1021
    EP_HASH *
1022
    ep_hash_new(
1023
                const char *name,               // for printing
1024
                EP_HASH_HASH_FUNCP *hfunc,      // alternate hash function
1025
                int tabsize)                    // hash table function size
1026
1027
    void
1028
    ep_hash_free(
1029
                EP_HASH *hp)                    // hash to free
1030
1031
    void *
1032
    ep_hash_search(
1033
                const EP_HASH *hp,              // hash to search
1034
                size_t keylen,                  // length of key
1035
                const void *key)                // pointer to key
1036
1037
    void *
1038
    ep_hash_insert(                     // returns old value for key
1039
                EP_HASH *hp,                    // hash to modify
1040
                size_t keylen,                  // length of key
1041
                const void *key,                // pointer to key
1042
                void *val)                      // value to insert
1043
1044
    ep_hash_forall(EP_HASH *hp,                 // hash to walk
1045
                void (func)(                    // function to call
1046
                        int keylen,                // key length
1047
                        const void *key,           // key value
1048
                        void *val,                 // value
1049
                        void *closure),            // from caller
1050
                void *closure)                  // passed to func
1051
1052
    ep_hash_dump(EP_TREE *tree,                 // tree to dump
1053
                FILE *sp)                       // stream to print on</programlisting>
1054
1055
      <para><remark>[[Should <function>ep_hash_dump</function> take the same
1056
      parameters as the usual object print routine? For that matter, should
1057
      there be a separate <function>ep_hash_dump</function> routine, or should
1058
      it just be a generic <function>ep_obj_dump</function>? Note that
1059
      <function>ep_hash_dump</function> is not implemented at this time, but
1060
      an internal (object-based) dump is.]]</remark></para>
1061
    </section>
1062
1063
    <section>
1064
      <title>Function Lists</title>
1065
1066
      <programlisting>    #include &lt;ep/ep_funclist.h&gt;
1067
1068
    EP_FUNCLIST *
1069
    ep_funclist_new(
1070
                const char *name)       // name for printing/debugging
1071
1072
    void
1073
    ep_funclist_free(EP_FUNCLIST *fp)   // list to free
1074
1075
    void
1076
    ep_funclist_push(EP_FUNCLIST *fp,   // list to push to
1077 11ef2ab4 Eric Allman
                void (*func)(           // the function to invoke
1078
                        void *closure,  // from the ep_funclist_push call
1079
                        void *arg),     // from the ep_funclist_invoke call
1080
                void *closure)          // the closure arg to pass to it
1081 d63b8179 Eric Allman
1082
    void
1083
    ep_funclist_pop(EP_FUNCLIST *fp)    // list to pop from, value discarded
1084
1085
    void
1086
    ep_funclist_clear(EP_FUNCLIST *fp)  // list to clear
1087
1088
    void
1089 11ef2ab4 Eric Allman
    ep_funclist_invoke(EP_FUNCLIST *fp, // invoke all functions in list
1090
                void *arg)              // second func arg</programlisting>
1091 d63b8179 Eric Allman
    </section>
1092
  </section>
1093
1094
  <section>
1095 42d9d20e Eric Allman
    <title>CRYPTOGRAPHIC SUPPORT</title>
1096
1097
    <para>The current implementation wraps the OpenSSL library, but it could
1098
    be retargeted.</para>
1099
1100 ac90b0f6 Eric Allman
    <para>Before any cryptographic functions can be used, the library must be
1101
    initialized:</para>
1102
1103
    <programlisting>void         ep_crypto_init(uint32_t flags)</programlisting>
1104
1105
    <para>At the moment flags is unused (just pass zero). There are also
1106
    several general purpose definitions, useful for declaring buffers without
1107
    memory allocation:</para>
1108
1109
    <informaltable border="1">
1110 11ef2ab4 Eric Allman
      <col width="4*"/>
1111 ac90b0f6 Eric Allman
1112 11ef2ab4 Eric Allman
      <col width="6*"/>
1113 ac90b0f6 Eric Allman
1114
      <tr>
1115
        <td><constant>EP_CRYPTO_MAX_PUB_KEY</constant></td>
1116
1117
        <td>Maximum length of a public key</td>
1118
      </tr>
1119
1120
      <tr>
1121
        <td><constant>EP_CRYPTO_MAX_SEC_KEY</constant></td>
1122
1123
        <td>Maximum length of a secret key</td>
1124
      </tr>
1125
1126
      <tr>
1127
        <td><constant>EP_CRYPTO_MAX_DIGEST</constant></td>
1128
1129
        <td>Maximum length of a message digest</td>
1130
      </tr>
1131
1132
      <tr>
1133
        <td><constant>EP_CRYPTO_MAX_DER</constant></td>
1134
1135
        <td>Maximum length of a DER-encoded key</td>
1136
      </tr>
1137
    </informaltable>
1138
1139 42d9d20e Eric Allman
    <section>
1140
      <title>Key Management</title>
1141
1142
      <para>Internally all keys are represented as <type>EP_CRYPTO_KEY</type>
1143
      variables, defined in <filename>ep_crypto.h</filename>. External
1144
      representations for keys may be either PEM (Privacy Enhanced Mail,
1145
      represented as text) or DER (Distinguished Encoding Rules, represented
1146
      in binary). PEM self identifies the type of key, but DER does not, so in
1147
      some cases the key type needs to be pre-arranged.</para>
1148
1149
      <programlisting>// on-disk key formats
1150
# define EP_CRYPTO_KEYFORM_UNKNOWN      0       // error
1151 ac90b0f6 Eric Allman
# define EP_CRYPTO_KEYFORM_PEM          1       // PEM (ASCII-encoded text)
1152 42d9d20e Eric Allman
# define EP_CRYPTO_KEYFORM_DER          2       // DER (binary ASN.1)</programlisting>
1153
1154
      <para>Internally, algorithms (e.g., for keys and hash/digest functions)
1155
      are represented by a scalar value. Keys also have to be identified as
1156
      public or secret.</para>
1157
1158 ac90b0f6 Eric Allman
      <remark>[[Note: DH is not supported at this time.]]</remark>
1159 42d9d20e Eric Allman
1160
      <programlisting>// key types
1161
# define EP_CRYPTO_KEYTYPE_UNKNOWN      0       // error
1162
# define EP_CRYPTO_KEYTYPE_RSA          1       // RSA
1163
# define EP_CRYPTO_KEYTYPE_DSA          2       // DSA
1164
# define EP_CRYPTO_KEYTYPE_EC           3       // Elliptic curve
1165
# define EP_CRYPTO_KEYTYPE_DH           4       // Diffie-Hellman
1166
1167
// flag bits
1168
# define EP_CRYPTO_F_PUBLIC             0x0000  // public key (no flags set)
1169
# define EP_CRYPTO_F_SECRET             0x0001  // secret key</programlisting>
1170
1171
      <para>Keys are represented as an <type>EP_CRYPTO_KEY</type>. New keys
1172
      can be created by giving the type of the key desired, the length of the
1173
      key in bits, and two other values that are interpreted by the key type.
1174
      The first is primarily for RSA and gives the exponent, and the second is
1175
      primarily for EC and gives the curve name.</para>
1176
1177
      <programlisting>EP_CRYPTO_KEY           *ep_crypto_key_create(
1178
                                int keytype,
1179
                                int keylen,
1180
                                int keyexp,
1181
                                const char *curve);</programlisting>
1182
1183
      <para>Keys can be read from or written to named files, open files, or
1184
      memory. All the read routines create and return a new key data
1185
      structure. If the <varname>keyform</varname> is
1186
      <constant>EP_CRYPTO_KEYFORM_PEM</constant> then the
1187
      <varname>keytype</varname> need not be specified.</para>
1188
1189
      <programlisting>EP_CRYPTO_KEY           *ep_crypto_key_read_file(
1190
                                const char *filename,
1191
                                int keyform,
1192
                                uint32_t flags);
1193
EP_CRYPTO_KEY           *ep_crypto_key_read_fp(
1194
                                FILE *fp,
1195
                                const char *filename,
1196
                                int keyform,
1197
                                uint32_t flags);
1198
EP_CRYPTO_KEY           *ep_crypto_key_read_mem(
1199
                                const void *buf,
1200
                                size_t buflen,
1201
                                int keyform,
1202
                                uint32_t flags);
1203
EP_STAT                 ep_crypto_key_write_file(
1204
                                EP_CRYPTO_KEY *key,
1205
                                const char *filename,
1206
                                int keyform,
1207
                                int cipher,
1208
                                uint32_t flags);
1209
EP_STAT                 ep_crypto_key_write_fp(
1210
                                EP_CRYPTO_KEY *key,
1211
                                FILE *fp,
1212
                                int keyform,
1213
                                int cipher,
1214
                                uint32_t flags);
1215
EP_STAT                 ep_crypto_key_write_mem(
1216
                                EP_CRYPTO_KEY *key,
1217
                                void *buf,
1218
                                size_t bufsize,
1219
                                int keyform,
1220
                                int cipher,
1221
                                uint32_t flags);</programlisting>
1222
1223
      <para>When finished with a key it must be freed.</para>
1224
1225
      <programlisting>void                    ep_crypto_key_free(
1226
                                EP_CRYPTO_KEY *key);</programlisting>
1227
1228
      <para>There are also some utility routines. A public and a secret key
1229
      can be compared to see if they match each other (same algorithm,
1230
      keysize, etc.) using <function>ep_crypto_key_compat</function>. Various
1231
      conversions are also included:
1232
      <function>ep_crypto_keyform_byname</function> converts a text string
1233
      (e.g., "pem") to an internal code,
1234
      <function>ep_crypto_keytype_fromkey</function> returns the type of a
1235
      key, and <function>ep_crypto_keytype_byname</function> converts a text
1236
      string to a type.</para>
1237
1238
      <programlisting>EP_STAT                 ep_crypto_key_compat(
1239
                                const EP_CRYPTO_KEY *pubkey,
1240
                                const EP_CRYPTO_KEY *seckey);
1241
int                     ep_crypto_keyform_byname(
1242
                                const char *fmt);
1243
int                     ep_crypto_keytype_fromkey(
1244
                                EP_CRYPTO_KEY *key);
1245
int                     ep_crypto_keytype_byname(
1246
                                const char *alg_name);</programlisting>
1247
    </section>
1248
1249
    <section>
1250
      <title>Message Digests (Hashes)</title>
1251
1252
      <para>Several message digest (cryptographic hash) algorithms are
1253
      supported. Text can be converted to one of these values, and the
1254
      algorithm type can be extracted from the internal form.</para>
1255
1256
      <programlisting>// digest algorithms (no more than 4 bits)
1257
# define EP_CRYPTO_MD_NULL      0
1258
# define EP_CRYPTO_MD_SHA1      1
1259
# define EP_CRYPTO_MD_SHA224    2
1260
# define EP_CRYPTO_MD_SHA256    3
1261
# define EP_CRYPTO_MD_SHA384    4
1262
# define EP_CRYPTO_MD_SHA512    5
1263
1264
int                     ep_crypto_md_alg_byname(
1265
                                const char *algname);
1266
int                     ep_crypto_md_type(
1267
                                EP_CRYPTO_MD *md);</programlisting>
1268
1269
      <para>Digests (type <type>EP_CRYPTO_MD</type>) can be created, freed,
1270
      and cloned. Cloning lets an application compute the a fixed part of a
1271
      digest (perhaps an unchanging header) and then produce separate digests
1272
      for individual records.</para>
1273
1274
      <programlisting>EP_CRYPTO_MD            *ep_crypto_md_new(
1275
                                int md_alg_id);
1276
EP_CRYPTO_MD            *ep_crypto_md_clone(
1277
                                EP_CRYPTO_MD *base_md);
1278
void                    ep_crypto_md_free(
1279
                                EP_CRYPTO_MD *md);</programlisting>
1280
1281
      <para>The typical lifetime of a digest is to be created (as above),
1282
      updated with additional data, possibly multiple times, and then
1283
      finalized to give the output hash.</para>
1284
1285
      <programlisting>EP_STAT                 ep_crypto_md_update(
1286
                                EP_CRYPTO_MD *md,
1287
                                void *data,
1288
                                size_t dsize);
1289
EP_STAT                 ep_crypto_md_final(
1290
                                EP_CRYPTO_MD *md,
1291
                                void *dbuf,
1292
                                size_t *dbufsize);</programlisting>
1293
    </section>
1294
1295
    <section>
1296
      <title>Signing and Verification</title>
1297
1298
      <para>Signing and verification are quite similar. A new internal
1299
      structure is created, using the same type as a message digest, data is
1300
      added to the existing hash, possibly multiple times, the signature is
1301
      created or verified, and finally the structure is freed.</para>
1302
1303
      <programlisting># define EP_CRYPTO_MAX_SIG      (1024 * 8)
1304
1305
EP_CRYPTO_MD            *ep_crypto_sign_new(
1306
                                EP_CRYPTO_KEY *skey,
1307
                                int md_alg_id);
1308
void                    ep_crypto_sign_free(
1309
                                EP_CRYPTO_MD *md);
1310
EP_STAT                 ep_crypto_sign_update(
1311
                                EP_CRYPTO_MD *md,
1312
                                void *dbuf,
1313
                                size_t dbufsize);
1314
EP_STAT                 ep_crypto_sign_final(
1315
                                EP_CRYPTO_MD *md,
1316
                                void *sbuf,
1317
                                size_t *sbufsize);
1318
1319
EP_CRYPTO_MD            *ep_crypto_vrfy_new(
1320
                                EP_CRYPTO_KEY *pkey,
1321
                                int md_alg_id);
1322
void                    ep_crypto_vrfy_free(
1323
                                EP_CRYPTO_MD *md);
1324
EP_STAT                 ep_crypto_vrfy_update(
1325
                                EP_CRYPTO_MD *md,
1326
                                void *dbuf,
1327
                                size_t dbufsize);
1328
EP_STAT                 ep_crypto_vrfy_final(
1329
                                EP_CRYPTO_MD *md,
1330
                                void *obuf,
1331
                                size_t obufsize);</programlisting>
1332
    </section>
1333
1334
    <section>
1335
      <title>Encryption and Decryption (Asymmetric)</title>
1336
1337
      <para>To be supplied.</para>
1338
    </section>
1339
1340
    <section>
1341
      <title>Encryption and Decryption (Symmetric Ciphers)</title>
1342
1343 ac90b0f6 Eric Allman
      <para>Symmetric Ciphers are driven by a Chaining Mode (how subsequent
1344
      blocks have the key modified to prevent replay and brute force attacks)
1345
      and the actual cipher itself. The chaining modes are:</para>
1346
1347
      <informaltable border="1">
1348 11ef2ab4 Eric Allman
        <col width="4*"/>
1349 ac90b0f6 Eric Allman
1350 11ef2ab4 Eric Allman
        <col width="6*"/>
1351 ac90b0f6 Eric Allman
1352
        <tr>
1353
          <td width=""><constant>EP_CRYPTO_MODE_CBC</constant></td>
1354
1355
          <td>Cipher Block Chaining</td>
1356
        </tr>
1357
1358
        <tr>
1359
          <td width=""><constant>EP_CRYPTO_MODE_CFB</constant></td>
1360
1361
          <td>Cipher Feedback mode</td>
1362
        </tr>
1363
1364
        <tr>
1365
          <td width=""><constant>EP_CRYPTO_MODE_OFB</constant></td>
1366
1367
          <td>Output Feedback mode</td>
1368
        </tr>
1369
      </informaltable>
1370
1371
      <para>The various cipher algorithms (which is equivalent to the key
1372
      type) are:</para>
1373
1374
      <informaltable border="1">
1375 11ef2ab4 Eric Allman
        <col width="4*"/>
1376 ac90b0f6 Eric Allman
1377 11ef2ab4 Eric Allman
        <col width="6*"/>
1378 ac90b0f6 Eric Allman
1379
        <tr>
1380
          <td><constant>EP_CRYPTO_SYMKEY_NONE</constant></td>
1381
1382
          <td>Error/unencrypted</td>
1383
        </tr>
1384
1385
        <tr>
1386
          <td><constant>EP_CRYPTO_SYMKEY_AES128</constant></td>
1387
1388
          <td>Advanced Encr Std, 128-bit key</td>
1389
        </tr>
1390
1391
        <tr>
1392
          <td><constant>EP_CRYPTO_SYMKEY_AES192</constant></td>
1393
1394
          <td>Advanced Encr Std, 192-bit key</td>
1395
        </tr>
1396
1397
        <tr>
1398
          <td><constant>EP_CRYPTO_SYMKEY_AES256</constant></td>
1399
1400
          <td>Advanced Encr Std, 256-bit key</td>
1401
        </tr>
1402
1403
        <tr>
1404
          <td><constant>EP_CRYPTO_SYMKEY_CAMELLIA128</constant></td>
1405
1406
          <td>Camellia, 128-bit key</td>
1407
        </tr>
1408
1409
        <tr>
1410
          <td><constant>EP_CRYPTO_SYMKEY_CAMELLIA192</constant></td>
1411
1412
          <td>Camellia, 192-bit key</td>
1413
        </tr>
1414
1415
        <tr>
1416
          <td><constant>EP_CRYPTO_SYMKEY_CAMELLIA256</constant></td>
1417
1418
          <td>Camellia, 256-bit key</td>
1419
        </tr>
1420
1421
        <tr>
1422
          <td><constant>EP_CRYPTO_SYMKEY_DES</constant></td>
1423
1424
          <td>Data Encryption Standard, single, 56-bit key</td>
1425
        </tr>
1426
1427
        <tr>
1428
          <td><constant>EP_CRYPTO_SYMKEY_3DES</constant></td>
1429
1430
          <td>Data Encryption Standard, triple, 128-bit key (112-bit
1431
          effective)</td>
1432
        </tr>
1433
1434
        <tr>
1435
          <td><constant>EP_CRYPTO_SYMKEY_IDEA</constant></td>
1436
1437
          <td>International Data Encryption Alg, 128-bit key</td>
1438
        </tr>
1439
      </informaltable>
1440
1441
      <para>One value from each table are "or"ed together to specify a full
1442
      symmetric cipher. The rest of the interface is as follows:</para>
1443
1444
      <programlisting>/*
1445
**      The cipher is set to encrypt or decrypt when the context
1446
**      is created.
1447
**
1448
**      ep_crypto_cipher_crypt is just shorthand for a single
1449 7023c91a Eric Allman
**      call to ep_crypto_cipher_update followed by a single
1450
**      call to ep_crypto_cipher_final.  Final pads out any
1451 ac90b0f6 Eric Allman
**      remaining block and returns that data.
1452
*/
1453
1454
EP_CRYPTO_CIPHER_CTX    *ep_crypto_cipher_new(
1455
                                uint32_t ciphertype,    // mode + keytype &amp; len
1456
                                uint8_t *key,           // the key
1457
                                uint8_t *iv,            // initialization vector
1458
                                bool enc);              // true =&gt; encrypt
1459
void                    ep_crypto_cipher_free(
1460
                                EP_CRYPTO_CIPHER_CTX *cipher);
1461
1462
EP_STAT                 ep_crypto_cipher_crypt(
1463
                                EP_CRYPTO_CIPHER_CTX *cipher,
1464
                                void *in,               // input data
1465
                                size_t inlen,           // input length
1466
                                void *out,              // output buffer
1467
                                size_t outlen);         // output buf size
1468 7023c91a Eric Allman
EP_STAT                 ep_crypto_cipher_update(
1469 ac90b0f6 Eric Allman
                                EP_CRYPTO_CIPHER_CTX *cipher,
1470
                                void *in,               // input data
1471
                                size_t inlen,           // input length
1472
                                void *out,              // output buffer
1473
                                size_t outlen);         // output buf size
1474 7023c91a Eric Allman
EP_STAT                 ep_crypto_cipher_final(
1475 ac90b0f6 Eric Allman
                                EP_CRYPTO_CIPHER_CTX *cipher,
1476
                                void *out,              // output buffer
1477
                                size_t outlen);         // output buf size</programlisting>
1478 42d9d20e Eric Allman
    </section>
1479
1480
    <section>
1481
      <title>Cryptography-specific Error Codes</title>
1482
1483
      <para>There are several status codes that may be returned from the
1484
      cryptography routines. These are all in module
1485
      EP_STAT_MOD_CRYPTO.</para>
1486
1487
      <informaltable border="1">
1488 11ef2ab4 Eric Allman
        <col width="4*"/>
1489 ac90b0f6 Eric Allman
1490 11ef2ab4 Eric Allman
        <col width="6*"/>
1491 ac90b0f6 Eric Allman
1492 42d9d20e Eric Allman
        <tr>
1493 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_DIGEST</errorcode></td>
1494 42d9d20e Eric Allman
1495
          <td>Failed to update or finalize a digest (hash)</td>
1496
        </tr>
1497
1498
        <tr>
1499 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_SIGN</errorcode></td>
1500 42d9d20e Eric Allman
1501
          <td>Failed to update or finalize a digest for signing</td>
1502
        </tr>
1503
1504
        <tr>
1505 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_VRFY</errorcode></td>
1506 42d9d20e Eric Allman
1507
          <td>Failed to update or finalize a digest for verification</td>
1508
        </tr>
1509
1510
        <tr>
1511 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_BADSIG</errorcode></td>
1512 42d9d20e Eric Allman
1513
          <td>Signature did not match</td>
1514
        </tr>
1515
1516
        <tr>
1517 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_KEYTYPE</errorcode></td>
1518 42d9d20e Eric Allman
1519
          <td>Unknown key type</td>
1520
        </tr>
1521
1522
        <tr>
1523 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_KEYFORM</errorcode></td>
1524 42d9d20e Eric Allman
1525
          <td>Unknown key format</td>
1526
        </tr>
1527
1528
        <tr>
1529 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_CONVERT</errorcode></td>
1530 42d9d20e Eric Allman
1531
          <td>Couldn't read or write a key</td>
1532
        </tr>
1533
1534
        <tr>
1535 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_KEYCREATE</errorcode></td>
1536 42d9d20e Eric Allman
1537
          <td>Couldn't create a new key</td>
1538
        </tr>
1539
1540
        <tr>
1541 ac90b0f6 Eric Allman
          <td><errorcode>EP_STAT_CRYPTO_KEYCOMPAT</errorcode></td>
1542 42d9d20e Eric Allman
1543 25e66e4f Eric Allman
          <td>Public and secret keys are incompatible</td>
1544 42d9d20e Eric Allman
        </tr>
1545 ac90b0f6 Eric Allman
1546
        <tr>
1547
          <td><errorcode>EP_STAT_CRYPTO_CIPHER</errorcode></td>
1548
1549
          <td>Symmetric cipher failure</td>
1550
        </tr>
1551 42d9d20e Eric Allman
      </informaltable>
1552
    </section>
1553
  </section>
1554
1555
  <section>
1556 d63b8179 Eric Allman
    <title>APPLICATION SUPPORT</title>
1557
1558
    <para>The following routines are intended to provide useful support to
1559
    applications, but are not otherwise fundamental</para>
1560
1561
    <section>
1562
      <title>Printing Flag Words, Etc.</title>
1563
1564
      <programlisting>    #include &lt;ep/ep_prflags.h&gt;
1565
1566
    void
1567
    ep_prflags(
1568
                u_int32 flagword,               // the flags word to print
1569
                EP_PRFLAGS_DESC *flaglist,      // descriptor of flags
1570
                FILE *out)                      // output stream
1571
1572
    typedef struct ep_prflags_desc
1573
    {
1574
            u_int32     bits;           // bits to compare against
1575
            u_int32     mask;           // mask against flagword
1576
            char        *name;          // printable name
1577
    } EP_PRFLAGS_DESC;</programlisting>
1578
1579
      <para>For example, given a descriptor of:</para>
1580
1581
      <programlisting>        0x0000, 0x0003, "READ",
1582
        0x0001, 0x0003, "WRITE",
1583
        0x0002, 0x0003, "READWRITE",
1584
        0x0003, 0x0003, "[INVALID MODE]",
1585
        0x0004, 0x0004, "NONBLOCK",
1586
        0x0008, 0x0008, "APPEND",
1587
        0,      0,      NULL</programlisting>
1588
1589
      <para>then a flagword of 0x0009 would print:</para>
1590
1591
      <para><computeroutput> 0009&lt;WRITE,APPEND&gt;</computeroutput></para>
1592
    </section>
1593
1594
    <section>
1595
      <title>Printing Helpers</title>
1596
1597
      <para>A few routines to make it easier to create string versions of
1598
      other type variables, e.g., for
1599
      <function>ep_stat_post</function>.</para>
1600
1601
      <programlisting>    #include &lt;ep/ep_pcvt.h&gt;
1602
1603
    char *ep_pcvt_str(size_t osize,             // output buffer size
1604
                char *obuf,                     // output buffer
1605
                const char *val)                // value to convert
1606
1607
    char *ep_pcvt_int(size_t osize,             // output buffer size
1608
                char *obuf,                     // output buffer
1609
                int base,                       // base of value
1610
                int val)                        // value to convert</programlisting>
1611
1612
      <para>All of these return their input buffer.</para>
1613
1614
      <para>The routine <function>ep_pcvt_str</function> truncates the value
1615
      to the indicated size. If the value won't fit, it renders
1616
      "<replaceable>beginning</replaceable>...<replaceable>end</replaceable>"
1617
      where <replaceable>end</replaceable> is the last three bytes of the
1618
      value.</para>
1619
    </section>
1620
1621
    <section>
1622
      <title>Application Messages</title>
1623
1624
      <para>Associated with status printing.</para>
1625
1626
      <programlisting>    #include &lt;ep/ep_app.h&gt;
1627
1628 174526d7 Eric Allman
    void ep_app_info(const char *fmt,           // printf-style format
1629
                ...)
1630
1631 d63b8179 Eric Allman
    void ep_app_warn(const char *fmt,           // printf-style format
1632
                ...)
1633
1634
    void ep_app_error(const char *fmt,          // printf-style format
1635
                ...)
1636
1637 b73e1ad7 Eric Allman
    void ep_app_fatal(const char *fmt,          // printf-style format
1638
                ...)
1639
1640 d63b8179 Eric Allman
    void ep_app_abort(const char *fmt,          // printf-style format
1641 b73e1ad7 Eric Allman
                ...)
1642
1643
    void ep_app_setflags(uint32_t flags)        // set operational tweaks</programlisting>
1644 d63b8179 Eric Allman
1645 174526d7 Eric Allman
      <para>The first three just print messages; the second two print the
1646 b73e1ad7 Eric Allman
      message and does not return. <function>ep_app_abort</function> generates
1647 174526d7 Eric Allman
      a core dump on termination. All five use printf formats.
1648 b73e1ad7 Eric Allman
      <function>ep_app_setflags</function> sets flags telling when to also do
1649
      logging; the flags are <constant>EP_APP_FLAG_LOGABORTS</constant>,
1650
      <constant>EP_APP_FLAG_LOGFATALS</constant>,
1651 174526d7 Eric Allman
      <constant>EP_APP_FLAG_LOGERRORS</constant>,
1652
      <constant>EP_APP_FLAG_LOGWARNINGS</constant>, and
1653
      <constant>EP_APP_FLAG_LOGINFOS</constant>. The log severity is different
1654
      for these various functions.</para>
1655 d63b8179 Eric Allman
1656
      <programlisting>    const char *
1657
    ep_app_getprogname(void)                    // get current program name</programlisting>
1658
1659
      <para>This is a portability wrapper that returns the name of the current
1660
      program (essentially, the last component of argv[0]).</para>
1661
    </section>
1662
1663
    <section>
1664
      <title>Printing Memory</title>
1665
1666
      <para>To print out a block of binary memory, use ep_hexdump.</para>
1667
1668
      <programlisting>    #include &lt;ep/ep_hexdump.h&gt;
1669
1670
    void
1671
    ep_hexdump(void *bufp,                       // block of memory to print
1672
        size_t buflen,                           // size of that block
1673
        FILE *fp,                                // output file
1674
        int format,                              // see description
1675
        size_t offset);                          // offset</programlisting>
1676
1677
      <para>This prints a block of memory as a hexadecimal dump, optionally
1678
      with an ASCII rendition. The offset printed starts at the
1679
      <varname>offset</varname> parameter (zero to make the printed offsets be
1680
      relative to <varname>bufp</varname>). The <varname>format</varname> may
1681
      be <constant>EP_HEXDUMP_HEX</constant> to print only the hexadecimal or
1682
      <constant>EP_HEXDUMP_ASCII</constant> to also show the bytes interpreted
1683
      as ASCII (unprintable characters are substituted).</para>
1684
    </section>
1685
  </section>
1686
1687
  <section>
1688
    <title>DEBUGGING, TRACING, ASSERTIONS</title>
1689
1690
    <para>Named flags, each settable from 0 to 127.</para>
1691
1692
    <para>When setting flags, wildcards can be used (only <quote>*</quote>
1693
    supported for now).</para>
1694
1695
    <programlisting>    #include &lt;ep/ep_dbg.h&gt;
1696
1697
    void
1698
    ep_dbg_init(void)                   // initialize debugging
1699
1700
    void
1701
    ep_dbg_set(const char *fspec)       // set debug flags (command line)
1702
1703
    void
1704
    ep_dbg_setto(const char *fpat,      // flag pattern
1705
                int lev)                // level
1706
1707
    EP_DBG  <replaceable>flag</replaceable> EP_DBG_INIT(           // opaque structure for flag
1708
                        name,           // external name of flag
1709
                        desc);          // description (internal use only)
1710
1711
    int
1712
    ep_dbg_level(EP_DBG *flag)          // return level of given flag
1713
1714
    bool
1715
    ep_dbg_test(EP_DBG *flag,
1716
                 int value)             // true if flag set to &gt;= value
1717
1718
    void
1719
    ep_dbg_printf(fmt, ...)             // print to EpStStddbg
1720
1721
    void
1722
    ep_dbg_cprintf(EP_DBG *flag,        // if flag level &gt;= value,
1723
                int value,
1724
                fmt, ...)               // print fmt etc as though printf.
1725
1726
    void
1727
    ep_dbg_setfile(FILE *fp)            // set debug output to indicated file
1728
1729
    void
1730
    ep_dbg_getfile(void)                // return current debug output file</programlisting>
1731
1732 c71b5a7a Eric Allman
    <para>Assertions are intended to catch "cannot happen" cases. They are not
1733
    necessarily fatal, depending on configuration controlled by administrative
1734
    parameters: <parameter>libep.assert.maxfailures</parameter> specifies the
1735
    number of assertion failures that will be tolerated before the process
1736
    aborts; however, every <parameter>libep.assert.resetinterval</parameter>
1737 cca7ea5f Eric Allman
    milliseconds the failure count is reset. For example, if
1738 c71b5a7a Eric Allman
    <parameter>libep.assert.maxfailures</parameter> is one, all assertion
1739 cca7ea5f Eric Allman
    failures are fatal; if zero, none are. It defaults to 100.
1740
    <parameter>libep.assert.resetinterval</parameter> defaults to 2000 (two
1741
    seconds).</para>
1742 d63b8179 Eric Allman
1743
    <programlisting>    #include &lt;ep/ep_assert.h&gt;
1744
1745 c71b5a7a Eric Allman
    EP_ASSERT(condition)                // fail if condition is false; returns the condition itself
1746 8d7fc458 Eric Allman
1747
    EP_ASSERT_ELSE(condition, recovery) // print and run recovery code if condition not satisfied
1748
1749
    EP_ASSERT_PRINT(                    // print assertion failure message
1750
            const char *msg,               // message to print
1751
            ...)                           // arguments to message
1752 c71b5a7a Eric Allman
    ep_assert_print(                    // print assertion failure with extra info and message
1753
            const char *file,              // file name
1754
            int line,                      // line number
1755
            const char *msg,               // message to print
1756
            ...)                           // arguments to message
1757 d63b8179 Eric Allman
1758 a346c64c Eric Allman
    EP_ASSERT_FAILURE(                  // abort process with message
1759
            const char *msg,               // message to print
1760
            ...)                           // arguments to message
1761
    ep_assert_failure(                  // abort process with extra info and message
1762
            const char *file,              // file name
1763
            int line,                      // line number
1764
            const char *msg,               // message to print
1765
            ...)                           // arguments to message
1766
1767 8d7fc458 Eric Allman
    void    (*EpAssertInfo)(void)       // if set, call to print additional information
1768 ddbd01b3 Eric Allman
    void    (*EpAssertAbort)(void)      // function to call before aborting
1769
    bool    EpAssertAllAbort            // if set, all assertions are immediately fatal</programlisting>
1770 a346c64c Eric Allman
1771 c71b5a7a Eric Allman
    <para>Programs may try to recover from assertion failures by testing the
1772
    result of <function>EP_ASSERT</function>, which will be true if the
1773
    condition holds. For example, either of these return an error code if a
1774
    pointer is <constant>NULL</constant>:</para>
1775
1776
    <programlisting>    if (!EP_ASSERT(p != NULL))
1777
        return EP_STAT_ASSERT_ABORT;
1778
1779
    EP_ASSERT_ELSE(p != NULL, return EP_STAT_ASSERT_ABORT);</programlisting>
1780
1781
    <para>Processes can force an abort as though they got an assertion failure
1782
    by calling <function>ep_assert_failure</function>. Note that this does not
1783
    attempt any recovery; <function>ep_assert_print</function> does the same
1784
    thing but does not abort. The macros
1785
    <function>EP_ASSERT_FAILURE</function> and
1786
    <function>EP_ASSERT_PRINT</function> do the same thing, but provide the
1787
    <parameter>file</parameter> name and <parameter>line</parameter> number in
1788
    the same way as the assertion tests. If the
1789 8d7fc458 Eric Allman
    <varname>EpAssertInfo</varname> variable is set, that function will be
1790
    called after printing the message but before aborting. It can be used to
1791
    dump process state for debugging. If the <varname>EpAssertAbort</varname>
1792
    variable is set, that function will be called after the message is printed
1793
    and immediately before the process aborts. This might do last minute
1794
    recovery or alternative termination (e.g., terminate just the thread
1795
    rather than the entire process).</para>
1796 d63b8179 Eric Allman
  </section>
1797
1798
  <section>
1799
    <title>THREAD SUPPORT</title>
1800
1801
    <para>These are mostly wrappers around the pthreads library, but they will
1802
    print errors if the <code>ep.thr</code> debug flag is set to at least
1803
    4.</para>
1804
1805
    <programlisting>#include &lt;ep/ep_thr.h&gt;
1806
1807
int
1808
ep_thr_mutex_init(EP_THR_MUTEX *mtx, int type);
1809
1810
int
1811
ep_thr_mutex_destroy(EP_THR_MUTEX *mtx);
1812
1813
int
1814
ep_thr_mutex_lock(EP_THR_MUTEX *mtx);
1815
1816
int
1817
ep_thr_mutex_trylock(EP_THR_MUTEX *mtx);
1818
1819
int
1820
ep_thr_mutex_unlock(EP_THR_MUTEX *mtx);
1821
1822
int
1823
ep_thr_mutex_check(EP_THR_MUTEX *mtx);
1824
1825
int
1826
ep_thr_cond_init(EP_THR_COND *cv);
1827
1828
int
1829
ep_thr_cond_destroy(EP_THR_COND *cv);
1830
1831
int
1832
ep_thr_cond_signal(EP_THR_COND *cv);
1833
1834
int
1835
ep_thr_cond_wait(EP_THR_COND *cv, EP_THR_MUTEX *mtx, EP_TIME_SPEC *timeout);
1836
1837
int
1838
ep_thr_cond_broadcast(EP_THR_COND *cv);
1839
1840
int
1841
ep_thr_rwlock_init(EP_THR_RWLOCK *rwl);
1842
1843
int
1844
ep_thr_rwlock_destroy(EP_THR_RWLOCK *rwl);
1845
1846
int
1847
ep_thr_rwlock_rdlock(EP_THR_RWLOCK *rwl);
1848
1849
int
1850
ep_thr_rwlock_tryrdlock(EP_THR_RWLOCK *rwl);
1851
1852
int
1853
ep_thr_rwlock_wrlock(EP_THR_RWLOCK *rwl);
1854
1855
int
1856
ep_thr_rwlock_tryrwlock(EP_THR_RWLOCK *rwl);
1857
1858
int
1859
ep_thr_rwlock_unlock(EP_THR_RWLOCK *rwl);</programlisting>
1860
1861
    <para>The ep_thr_*_check routines check the structures for consistency and
1862
    print an error; this is only for debugging. <remark>This should be
1863
    expanded to include spawning threads etc.; for the time being just use the
1864
    pthreads primitives.</remark></para>
1865
1866
    <para>There is also a basic thread pool implementation:</para>
1867
1868
    <programlisting>#include &lt;ep/ep_thr.h&gt;
1869
1870
void
1871
ep_thr_pool_init(
1872
        int min_threads,
1873
        int max_threads,
1874
        uint32_t flags);
1875
1876
void
1877
ep_thr_pool_run(
1878
        void (*func)(void *),
1879
        void *arg);</programlisting>
1880
1881
    <para>Thread pools are initially started with
1882
    <varname>min_threads</varname> workers (which may be zero; defaults to the
1883
    <parameter>libep.thr.pool.min_workers</parameter> administrative
1884
    parameter, or 1 if that is not set). Threads will be spawned as necessary
1885
    up to <varname>max_threads</varname> total workers (defaults to
1886
    <parameter>libep.thr.pool.max_workers</parameter>; if that is not set,
1887
    defaults to twice the number of cores available).</para>
1888
1889
    <para>Threads are run in essentially the same way as spawning a pthreads
1890
    thread; this is really just a convenience wrapper around that so resources
1891
    can be better controlled.</para>
1892
  </section>
1893
1894
  <section>
1895
    <title>LOGGING</title>
1896
1897
    <para>Messages may be logged together with a status code:</para>
1898
1899
    <programlisting>#include &lt;ep/ep_log.h&gt;
1900
1901
void
1902
ep_log_init(
1903
        const char *tag,
1904
        int logfac,
1905 58c51fe6 Eric Allman
        FILE *logfile);
1906
1907
void
1908
ep_log_addmethod(
1909
        void (*func)(void *ctx, EP_STAT estat, const char *fmt, va_list ap),
1910
        void *ctx,
1911
        int minsev);
1912 d63b8179 Eric Allman
1913
void
1914
ep_log(
1915
        EP_STAT estat,
1916
        const char *fmt,
1917 1081f575 Eric Allman
        ...);
1918
1919
void
1920
ep_logv(
1921
        EP_STAT estat,
1922
        const char *fmt,
1923
        va_list va);</programlisting>
1924 d63b8179 Eric Allman
1925 58c51fe6 Eric Allman
    <para>The <function>ep_log</function> and <function>ep_logv</function>
1926
    routines send information to various system logs. The default is to send
1927
    to <function>syslog</function>(3) and to <symbol>stderr</symbol>. You can
1928
    disable or change this by calling <function>ep_log_init</function> before
1929
    the first logging call, and extend it by passing another logging method to
1930
    <function>ep_log_addmethod</function>, which causes
1931
    <parameter>func</parameter> to be called whenever a message with severity
1932
    at least the value of the <parameter>minsev</parameter> parameter
1933
    (<constant>EP_STAT_SEV_OK</constant>,
1934
    <constant>EP_STAT_SEV_WARN</constant>,
1935
    <constant>EP_STAT_SEV_ERROR</constant>,
1936
    <constant>EP_STAT_SEV_SEVERE</constant>,
1937
    <constant>EP_STAT_SEV_ABORT</constant>).</para>
1938
1939
    <para>The status code is logged together with the printf-style message.
1940
    The syslog severity is determined from the severity of the status code:
1941
    <constant>OK</constant> codes log an <constant>LOG_INFO</constant>
1942
    message, <constant>WARN</constant> codes log a
1943
    <constant>LOG_WARNING</constant> message, <constant>ERROR</constant> codes
1944
    log a <constant>LOG_ERR</constant> message, <constant>SEVERE</constant>
1945
    codes log a <constant>LOG_CRIT</constant> message, and
1946
    <constant>ABORT</constant> codes log a <constant>LOG_ALERT</constant>
1947
    message.</para>
1948 d63b8179 Eric Allman
  </section>
1949
1950
  <section>
1951
    <title>ARGUMENT CRACKING</title>
1952
1953
    <para><remark>Not implemented at this time</remark>. To help with parsing
1954
    command line arguments. A descriptor is declared as follows:</para>
1955
1956
    <programlisting>    #include &lt;ep/ep_crackargv.h&gt;
1957
1958
    unsigned long       NTests;
1959
    long                Seed;
1960
    static char         *FileName;
1961
1962
    EP_CAV_DESCR        ArgvDescriptor[] =
1963
    {
1964
        { "debug",              EP_CAV_TYPE(debug),     'D',    5,
1965
                "Debug",                "debug-flags",          NULL,
1966
                EP_CAV_FLAG_NOARGS
1967
        },
1968
        { "ntests",             EP_CAV_TYPE(ulong),     'n',    1,
1969
                "Number of tests",      NULL,                   &amp;NTests,
1970
                EP_CAV_FLAG_REQUIRED
1971
        },
1972
        { "seed",               EP_CAV_TYPE(long),      's',    1,
1973
                NULL,                   NULL,                   &amp;Seed,
1974
                EP_CAV_FLAG_NONE
1975
        }
1976
        { NULL,                 EP_CAV_TYPE(string),    '\0',   0,
1977
                NULL,                   NULL,                   &amp;FileName,
1978
                EP_CAV_FLAG_NONE
1979
        }
1980
        EP_CAV_DESCR_END
1981
    };</programlisting>
1982
1983
    <para>The <function>ep_crackargv</function> routine is then called with an
1984
    argument vector and a descriptor:</para>
1985
1986
    <programlisting>    stat = ep_crackargv(const char **argv, const EP_CAV_DESCR *descr);</programlisting>
1987
1988
    <para>The argument vector is then matched to the descriptor and
1989
    appropriate bindings done. Duplicate and missing flags are diagnosed and
1990
    all conversions are done.</para>
1991
1992
    <para>The fields in the descriptor are:</para>
1993
1994
    <itemizedlist>
1995
      <listitem>
1996
        <para>The long name. On Unix, this is matched against arguments
1997
        beginning "--". This is case independent.</para>
1998
      </listitem>
1999
2000
      <listitem>
2001
        <para>The data type. This is always
2002
        <constant>EP_CAV_TYPE</constant>(something), which calls the
2003
        conversion routine named <function>ep_cvt_txt_to_something</function>
2004
        passing it the value as a text string and a pointer to the output
2005
        location (see below).</para>
2006
      </listitem>
2007
2008
      <listitem>
2009
        <para>The short (single character) name. On Unix, this is matched
2010
        against arguments beginning "-". Flags without values can be combined
2011
        into one flag -- that is, if "-a -b" sets two boolean flags, "-ab"
2012
        does the same thing.</para>
2013
      </listitem>
2014
2015
      <listitem>
2016
        <para>The number of bytes of the long name that must match. This
2017
        allows abbreviation of names. See below.</para>
2018
      </listitem>
2019
2020
      <listitem>
2021
        <para>The prompt. If flags are required and a prompt is available,
2022
        <function>ep_crackargv</function> can prompt for missing parameters.
2023
        Not yet implemented.</para>
2024
      </listitem>
2025
2026
      <listitem>
2027
        <para>The usage message to describe this parameter. Defaults to the
2028
        long name.</para>
2029
      </listitem>
2030
2031
      <listitem>
2032
        <para>The value pointer. A pointer to the data area in which to store
2033
        the results. If NULL, this parameter cannot accept a value.</para>
2034
      </listitem>
2035
2036
      <listitem>
2037
        <para>Flag bits, as described below.</para>
2038
      </listitem>
2039
    </itemizedlist>
2040
2041
    <para>Long flag names can be abbreviated. All characters of the command
2042
    line must match the descriptor, but only the number indicated in the "must
2043
    match" field need be present. For example, given a name in the descriptor
2044
    of "ntests" with a "must match" field of 2 will match "--ntests",
2045
    "--ntes", "--nt", but not "--ntext", "--n", or "--nteststotry".</para>
2046
2047
    <para>Flag bits include:</para>
2048
2049
    <variablelist>
2050
      <varlistentry>
2051
        <term><constant>EP_CAV_FLAG_NONE</constant></term>
2052
2053
        <listitem>
2054
          <para>No special processing</para>
2055
        </listitem>
2056
      </varlistentry>
2057
2058
      <varlistentry>
2059
        <term><constant>EP_CAV_FLAG_NOARGS</constant></term>
2060
2061
        <listitem>
2062
          <para>This parameter takes no arguments (e.g., a boolean)</para>
2063
        </listitem>
2064
      </varlistentry>
2065
2066
      <varlistentry>
2067
        <term><constant>EP_CAV_FLAG_NOMORE</constant></term>
2068
2069
        <listitem>
2070
          <para>This consumes all remaining arguments (normally
2071
          EP_CAV_TYPE(Vector))</para>
2072
        </listitem>
2073
      </varlistentry>
2074
2075
      <varlistentry>
2076
        <term><constant>EP_CAV_FLAG_MULTVAL</constant></term>
2077
2078
        <listitem>
2079
          <para>There can be multiple values for this parameter (only relevant
2080
          for flags)</para>
2081
        </listitem>
2082
      </varlistentry>
2083
2084
      <varlistentry>
2085
        <term><constant>EP_CAV_FLAG_REQUIRED</constant></term>
2086
2087
        <listitem>
2088
          <para>If this parameter is missing it is an error</para>
2089
        </listitem>
2090
      </varlistentry>
2091
    </variablelist>
2092
2093
    <para>Predefined types and the type of the corresponding value pointer
2094
    are:</para>
2095
2096
    <simplelist columns="3" type="horiz">
2097
      <member>bool</member>
2098
2099
      <member>bool_t *</member>
2100
2101
      <member>Booleans. Should have
2102
      <constant>EP_CAV_FLAG_NOARGS</constant>.</member>
2103
2104
      <member>string</member>
2105
2106
      <member>const char **</member>
2107
2108
      <member>Strings.</member>
2109
2110
      <member>long</member>
2111
2112
      <member>long *</member>
2113
2114
      <member>Signed long integers.</member>
2115
2116
      <member>ulong</member>
2117
2118
      <member>unsigned long *</member>
2119
2120
      <member>Unsigned long integers.</member>
2121
2122
      <member>double</member>
2123
2124
      <member>double *</member>
2125
2126
      <member>Double point floating point.</member>
2127
2128
      <member>vector</member>
2129
2130
      <member>const char ***</member>
2131
2132
      <member>Vectors. Must have the EP_CAV_FLAG_MULTVAL flag set. Can only be
2133
      one, and it must be at the end.</member>
2134
2135
      <member>debug</member>
2136
2137
      <member>NULL</member>
2138
2139
      <member>Sets debug flags</member>
2140
    </simplelist>
2141
2142
    <para>To appear:</para>
2143
2144
    <simplelist columns="2" type="horiz">
2145
      <member>int8</member>
2146
2147
      <member>int8_t *</member>
2148
2149
      <member>uint8</member>
2150
2151
      <member>uint8_t *</member>
2152
2153
      <member>int16</member>
2154
2155
      <member>int16_t *</member>
2156
2157
      <member>uint16</member>
2158
2159
      <member>uint16_t *</member>
2160
2161
      <member>int32</member>
2162
2163
      <member>int32_t *</member>
2164
2165
      <member>uint32</member>
2166
2167
      <member>uint32_t *</member>
2168
2169
      <member>int64</member>
2170
2171
      <member>int64_t *</member>
2172
2173
      <member>uint64</member>
2174
2175
      <member>uint64_t *</member>
2176
2177
      <member>admparam</member>
2178
2179
      <member>const char *</member>
2180
    </simplelist>
2181
2182
    <para>Administrative parameters (see
2183
    <function>ep_adm_getintparam</function> and
2184
    <function>ep_adm_getstrparam</function>). The value pointer is the name of
2185
    the parameter to set.</para>
2186
2187
    <para>New parameter types can be trivially created by defining new
2188
    routines named
2189
    <function>ep_cvt_txt_to_</function><replaceable>type</replaceable> that
2190
    take a <type>const char *</type> as input and a
2191
    <type><replaceable>type</replaceable> *</type> output pointer. They return
2192
    <type>EP_STAT</type>. Conversion errors should fail.</para>
2193
  </section>
2194
2195
  <section>
2196
    <title>MISCELLANEOUS STUFF</title>
2197
2198
    <programlisting linenumbering="numbered">    EP_UT_BITSET(uint32 bits,           // return true if any bits...
2199
                uint32_t word)          // ... are set in word
2200
2201
/*
2202
    EP_UT_SETBIT(uint32_t bits,         // set these bits...
2203
                uint32_t word)          // ... in this word
2204
2205
    EP_UT_CLRBIT(uint32 bits,           // clear these bits...
2206
                uint32_t word)          // ... in this word
2207
*/
2208
2209
    EP_UT_BITMAP(               // declare bitmap
2210
        name,                           // name of bitmap to declare
2211
        nbits)                          // number of bits in map
2212
2213
    EP_UT_CLRBITMAP(            // clear bitmap
2214
        name)                           // bitmap to clear
2215
2216
    EP_UT_BITNSET(int bitn,             // true if bit number bitn is set...
2217
                bitmap)                 // ... in this map
2218
2219
    EP_UT_SETBITN(int bitn,             // set bit number bitn...
2220
                bitmap)                 // ... in this map
2221
2222
    EP_UT_CLRBITN(int bitn,             // clear bit number bitn...
2223
                bitmap)                 // ... in this map
2224
2225
    EP_GEN_DEADBEEF                     // a value you can use to trash memory</programlisting>
2226
2227
    <warning>
2228
      <para>There is no checking for the BITMAP routines
2229
      (<function>EP_UT_BITNSET</function>, <function>EP_UT_SETBITN</function>,
2230
      <function>EP_UT_CLRBITN</function>) to ensure that the bit indicated is
2231
      in range for the size of the bitmap.</para>
2232
    </warning>
2233
  </section>
2234
2235
  <section>
2236
    <title>INTERACTION WITH THE ENVIRONMENT</title>
2237
2238
    <section>
2239
      <title>Global Administrative Parameters</title>
2240
2241
      <para>There are a bunch of parameters that we would prefer to be
2242
      settable at run time. We'll model this on sysctl(8). Before accessing
2243
      parameters you must read them using
2244
      <function>ep_adm_readparams</function>. This routine takes a
2245
      <varname>name</varname> and then looks for a file in a search path. That
2246
      path may be set using the PARAM_PATH environment variable, and defaults
2247
      to:<programlisting>.ep_adm_params:~/.ep_adm_params:/usr/local/etc/ep_adm_params:/etc/ep_adm_params</programlisting>For
2248
      example, searching for a name such as "<userinput>defaults</userinput>"
2249
      will first try to read the file
2250
      <filename>.ep_adm_params/defaults</filename>. If that is found the
2251
      search stops, otherwise it trys
2252
      <filename>~/.ep_adm_params/defaults</filename>, and so forth. New values
2253
      replace old ones, so programs that want to search more than one file
2254
      should start with the most generic one and continue to the least generic
2255
      one.</para>
2256
2257
      <programlisting>    #include &lt;ep/ep_adm.h&gt;
2258
2259
    void
2260
    ep_adm_readparams(
2261
                const char *name)       // basename of the parameter file
2262
2263
    int
2264
    ep_adm_getintparam(
2265
                const char *name,       // name of the parameter
2266
                int default)            // value if parameter not set
2267
2268 dc11518f Eric Allman
    long
2269 d63b8179 Eric Allman
    ep_adm_getlongparam(
2270
                const char *name,       // name of the parameter
2271
                long default)           // value if parameter not set
2272
2273 c7258388 Eric Allman
    intmax_t
2274
    ep_adm_getintmaxparam(
2275
                const char *name,       // name of the parameter
2276
                intmax_t default)       // value if the parameter is not set
2277
2278 dc11518f Eric Allman
    bool
2279 d63b8179 Eric Allman
    ep_adm_getboolparam(
2280
                const char *name,       // name of the parameter
2281
                bool default)           // value if parameter not set
2282
2283 dc11518f Eric Allman
    const char *
2284 d63b8179 Eric Allman
    ep_adm_getstrparam(
2285
                const char *name,       // name of the parameter
2286
                char *default)          // value if parameter not set</programlisting>
2287
2288
      <para>Names are structured kind of like <function>sysctl</function>
2289
      arguments or X Resource names, e.g.,
2290
      "<varname>libep.stream.hfile.bsize</varname>". You must read one or more
2291
      parameter files before getting parameters.</para>
2292 59c6c7e0 Eric Allman
2293
      <para>If the <constant>EP_CONF_ADM_ENV_OVERRIDE</constant> defined
2294
      constant is set to <constant>1</constant> during compilation, parameters
2295
      can be overridden in the environment. For example,</para>
2296
2297
      <programlisting>env swarm.gdp.routers=foo.example.com gdplogd</programlisting>
2298
2299
      <para>This only works if the program is running as a non-root user
2300
      without setuid.</para>
2301 d63b8179 Eric Allman
    </section>
2302
2303
    <section>
2304
      <title>Terminal Video Sequences and Characters</title>
2305
2306
      <para>Mostly for debugging use. Right now compiled in for ANSI
2307
      xterms.</para>
2308
2309
      <programlisting>    #include &lt;ep/ep_string.h&gt;
2310
2311
    struct epVidSequences
2312
    {
2313
        const char    *vidnorm;       // set video to normal
2314
        const char    *vidbold;       // set video to bold
2315
        const char    *vidfaint;      // set video to faint
2316
        const char    *vidstout;      // set viadeo to "standout"
2317
        const char    *viduline;      // set video to underline
2318
        const char    *vidblink;      // set video to blink
2319
        const char    *vidinv;        // set video to invert
2320
        const char    *vidfgblack;    // set foreground black
2321
        const char    *vidfgred;      // set foreground red
2322
        const char    *vidfggreen;    // set foreground green
2323
        const char    *vidfgyellow;   // set foreground yellow
2324
        const char    *vidfgblue;     // set foreground blue
2325
        const char    *vidfgmagenta;  // set foreground magenta
2326
        const char    *vidfgcyan;     // set foreground cyan
2327
        const char    *vidfgwhite     // set foreground white
2328
        const char    *vidbgblack;    // set background black
2329
        const char    *vidbgred;      // set background red
2330
        const char    *vidbggreen;    // set background green
2331
        const char    *vidbgyellow;   // set background yellow
2332
        const char    *vidbgblue      // set background blue
2333
        const char    *vidbgmagenta;  // set background magenta
2334
        const char    *vidbgcyan;     // set background cyan
2335
        const char    *vidbtwhite;    // set background white
2336
    } *EpVid;
2337
2338
    struct epCharSequences
2339
    {
2340
        const char    *lquote;        // left quote sequence
2341
        const char    *rquote;        // right quote sequence
2342
        const char    *copyright;     // copyright symbol
2343
        const char    *degree;        // degree symbol
2344
        const char    *micro;         // micro symbol
2345
        const char    *plusminus;     // +/- symbol
2346
        const char    *times;         // mathematical times symbol
2347
        const char    *divide;        // mathematical division symbol
2348
        const char    *null;          // "null" symbol
2349
        const char    *notequal;      // mathematical "not equal" symbol
2350
        const char    *unprintable;   // substitution for unprintable characters
2351
        const char    *paragraph;     // paragraph symbol
2352
        const char    *section;       // section symbol
2353
        const char    *notsign;       // logical not symbol
2354
        const char    *infinity;      // infinity symbol
2355
    } *EpChar;
2356
2357
    EP_STAT   ep_str_vid_set(         // set video style
2358
        const char    *type);         // NULL, "none", or "ansi"
2359
2360
    EP_STAT   ep_str_char_set(        // set special characters
2361
        const char    *type);         // character set (see below)</programlisting>
2362
2363
      <para>These structures contain character sequences used for printing
2364
      video controls and special characters respectively. The
2365
      <function>ep_str_vid_set</function> routines allows you to choose the
2366
      video escape sequences. Passing <constant>NULL</constant> causes an
2367
      educated guess at the default on the basis of the <envar>TERM</envar>
2368
      environment variable. Any <envar>TERM</envar> setting beginning with
2369
      "<constant>xterm</constant>" is the same as specifying
2370
      "<constant>ansi</constant>" as the type and anything else is the same as
2371
      specifying "<constant>none</constant>" as the type (which sets all the
2372
      video strings to null strings). Blessedly, xterm doesn't seem to render
2373
      blink, nor faint or standout. Bold and blink are both rendered in bold.
2374
      So, for best results use bold, uline, and inv (and of course
2375
      norm).</para>
2376
2377
      <para>The <function>ep_str_char_set</function> allows you to set special
2378
      character encodings. Its parameter may be <constant>NULL</constant>
2379
      (which guesses based on the <envar>LANG</envar> environment variable),
2380
      "<constant>ascii</constant>", "<constant>iso-8859-1</constant>",
2381
      "<constant>iso-latin-1</constant>", "<constant>utf-8</constant>", or
2382
      "<constant>utf8</constant>". The mappings are shown in the following
2383
      table:</para>
2384
2385
      <informaltable frame="box" rules="all">
2386
        <thead>
2387
          <tr align="center">
2388
            <th>Name</th>
2389
2390
            <th>ASCII</th>
2391
2392
            <th>Other Charset</th>
2393
          </tr>
2394
        </thead>
2395
2396
        <tbody>
2397
          <tr>
2398
            <td>lquote</td>
2399
2400
            <td align="center">`</td>
2401
2402 dc11518f Eric Allman
            <td align="center">&laquo;</td>
2403 d63b8179 Eric Allman
          </tr>
2404
2405
          <tr>
2406
            <td>rquote</td>
2407
2408
            <td align="center">'</td>
2409
2410 dc11518f Eric Allman
            <td align="center">&raquo;</td>
2411 d63b8179 Eric Allman
          </tr>
2412
2413
          <tr>
2414
            <td>copyright</td>
2415
2416
            <td align="center">(c)</td>
2417
2418 dc11518f Eric Allman
            <td align="center">&copy;</td>
2419 d63b8179 Eric Allman
          </tr>
2420
2421
          <tr>
2422
            <td>degree</td>
2423
2424
            <td align="center">deg</td>
2425
2426 42d9d20e Eric Allman
            <td align="center">&deg;</td>
2427 d63b8179 Eric Allman
          </tr>
2428
2429
          <tr>
2430
            <td>micro</td>
2431
2432
            <td align="center">u</td>
2433
2434 dc11518f Eric Allman
            <td align="center">&micro;</td>
2435 d63b8179 Eric Allman
          </tr>
2436
2437
          <tr>
2438
            <td>plusminus</td>
2439
2440
            <td align="center">+/-</td>
2441
2442 dc11518f Eric Allman
            <td align="center">&plusmn;</td>
2443 d63b8179 Eric Allman
          </tr>
2444
2445
          <tr>
2446
            <td>times</td>
2447
2448
            <td align="center">*</td>
2449
2450 dc11518f Eric Allman
            <td align="center">&times;</td>
2451 d63b8179 Eric Allman
          </tr>
2452
2453
          <tr>
2454
            <td>divide</td>
2455
2456
            <td align="center">/</td>
2457
2458 dc11518f Eric Allman
            <td align="center">&divide;</td>
2459 d63b8179 Eric Allman
          </tr>
2460
2461
          <tr>
2462
            <td>null</td>
2463
2464
            <td align="center">NULL</td>
2465
2466 42d9d20e Eric Allman
            <td align="center">&empty;</td>
2467 d63b8179 Eric Allman
          </tr>
2468
2469
          <tr>
2470
            <td>notequal</td>
2471
2472
            <td align="center">!=</td>
2473
2474 dc11518f Eric Allman
            <td align="center">&ne;</td>
2475 d63b8179 Eric Allman
          </tr>
2476
2477
          <tr>
2478
            <td>unprintable</td>
2479
2480
            <td align="center">?</td>
2481
2482 dc11518f Eric Allman
            <td align="center">&#8999;</td>
2483 d63b8179 Eric Allman
          </tr>
2484
2485
          <tr>
2486
            <td>paragraph</td>
2487
2488
            <td align="center">pp.</td>
2489
2490 dc11518f Eric Allman
            <td align="center">&para;</td>
2491 d63b8179 Eric Allman
          </tr>
2492
2493
          <tr>
2494
            <td>section</td>
2495
2496
            <td align="center">sec.</td>
2497
2498 dc11518f Eric Allman
            <td align="center">&sect;</td>
2499 d63b8179 Eric Allman
          </tr>
2500
2501
          <tr>
2502
            <td>notsign</td>
2503
2504
            <td align="center">(not)</td>
2505
2506 dc11518f Eric Allman
            <td align="center">&not;</td>
2507 d63b8179 Eric Allman
          </tr>
2508
2509
          <tr>
2510
            <td>infinity</td>
2511
2512
            <td align="center">(inf)</td>
2513
2514 dc11518f Eric Allman
            <td align="center">&infin;</td>
2515 d63b8179 Eric Allman
          </tr>
2516
        </tbody>
2517
      </informaltable>
2518
2519
      <para>Other values may be added to this table as needed.</para>
2520
2521
      <para>Example:</para>
2522
2523
      <programlisting>    fprintf(ep_dbg_getfile(), "Input was %s%s%s\n",
2524
                        EpVidSeq.lquote, input, EpVidSeq.rquote);</programlisting>
2525
    </section>
2526 55b46f00 Eric Allman
2527
    <section>
2528
      <title>Startup/Shutdown</title>
2529
2530
      <para>If running under <systemitem>systemd</systemitem>-based versions
2531
      of Linux, it is possible to signal status changes to the startup
2532
      environment, notably about system startup and shutdown. This is only
2533
      relevant for programs that run as system daemons.</para>
2534
2535
      <programlisting>#include &lt;ep/ep_sd.h&gt;
2536
2537
void
2538
ep_sd_notifyf(
2539
        const char *fmt,
2540
        ...);</programlisting>
2541
2542
      <para>The <parameter>fmt</parameter> and any arguments are printed a'la
2543
      <function>printf</function>(3) to a system buffer that is delivered to
2544
      <systemitem>systemd</systemitem>. The format of that buffer is defined
2545
      by <function>sd_notify</function>(3) and is not detailed here. Roughly,
2546
      each line of the output looks like an environment variable definition.
2547
      For example:</para>
2548
2549
      <programlisting>// to inform the system that this service is ready:
2550
ep_sd_notifyf(
2551
        "READY=1");
2552
2553
// to inform the system that this service is shutting down:
2554
ep_sd_notifyf(
2555
        "STOPPING=1\n"
2556
        "STATUS=Exiting on user signal %d\n",
2557
        sig);</programlisting>
2558
2559
      <para>Important values include <literal>READY=1</literal>,
2560
      <literal>RELOADING=1</literal>, <literal>WATCHDOG=1</literal>, and
2561
      <literal>STOPPING=...</literal>.</para>
2562
2563
      <para>If the <constant>EP_OSCF_HAS_SD_NOTIFY</constant> flag is set to
2564
      zero at compilation time, this call is a no-op. This is the case on most
2565
      systems.</para>
2566
2567
      <remark>This should really abstract the syntax out more, rather than
2568
      making it <systemitem>systemd</systemitem> specific, so that it can
2569
      potentially be used on other systems.</remark>
2570
    </section>
2571 d63b8179 Eric Allman
  </section>
2572
2573
  <section>
2574
    <title>TRANSLATIONS</title>
2575
2576 b0136566 Eric Allman
    <para>Simple string translations for certain external formats, for example
2577
    as might be used by URLs or Quoted-Printable.</para>
2578 d63b8179 Eric Allman
2579
    <programlisting>    #include &lt;ep/ep_xlate.h&gt;
2580
2581
    int
2582
    ep_xlate_in(
2583 b0136566 Eric Allman
        const void *ext,                // external (encoded) string input
2584 d63b8179 Eric Allman
        uchar_t *out,                   // pointer to output buffer
2585
        size_t olen,                    // length of output buffer
2586
        char stopchar,                  // input char to stop at
2587
        uint32_t how)                   // what kind of translations to do</programlisting>
2588
2589 b0136566 Eric Allman
    <para>Translates an external form (with encodings) into internal form
2590
    (potentially 8-bit binary). Returns the number of output bytes. The "how"
2591
    parameter tells what translations to do -- they can be combined:</para>
2592 d63b8179 Eric Allman
2593
    <table>
2594
      <title>EP_XLATE "how" Bits</title>
2595
2596
      <tgroup cols="2">
2597 11ef2ab4 Eric Allman
        <colspec/>
2598 d63b8179 Eric Allman
2599 11ef2ab4 Eric Allman
        <colspec colwidth="3*"/>
2600 d63b8179 Eric Allman
2601
        <tbody>
2602
          <row>
2603
            <entry>EP_XLATE_PERCENT</entry>
2604
2605
            <entry>Translate "%xx" like ESMTP</entry>
2606
          </row>
2607
2608
          <row>
2609
            <entry>EP_XLATE_BSLASH</entry>
2610
2611
            <entry>Translate backslash escapes like C</entry>
2612
          </row>
2613
2614
          <row>
2615
            <entry>EP_XLATE_AMPER</entry>
2616
2617
            <entry>Translate "&amp;name;" like HTML</entry>
2618
          </row>
2619
2620
          <row>
2621
            <entry>EP_XLATE_PLUS</entry>
2622
2623
            <entry>Translate "+xx" like DNSs</entry>
2624
          </row>
2625
2626
          <row>
2627
            <entry>EP_XLATE_EQUAL</entry>
2628
2629
            <entry>Translate "=xx" like quoted-printable</entry>
2630
          </row>
2631
2632
          <row>
2633
            <entry>EP_XLATE_8BIT</entry>
2634
2635
            <entry>Translate 8-bit characters
2636
            (<function>ep_xlate_out</function> only)</entry>
2637
          </row>
2638 b0136566 Eric Allman
2639
          <row>
2640
            <entry>EP_XLATE_NPRINT</entry>
2641
2642
            <entry>Translate non-printable characters
2643
            (<function>ep_xlate_out</function> only)</entry>
2644
          </row>
2645 d63b8179 Eric Allman
        </tbody>
2646
      </tgroup>
2647
    </table>
2648
2649
    <programlisting>    int
2650
    ep_xlate_out(
2651 b0136566 Eric Allman
        const void *in,                 // internal (not encoded) input string
2652 d63b8179 Eric Allman
        size_t ilen,                    // length of in
2653 b0136566 Eric Allman
        FILE *osp,                      // encoded output stream pointer
2654 d63b8179 Eric Allman
        const char *forbid,             // list of characters to encode
2655
        uint32_t how)                   // how to do output translations</programlisting>
2656
2657
    <para>Unlike input, it doesn't make sense to list more than one of
2658
    <constant>EP_XLATE_PERCENT</constant>,
2659
    <constant>EP_XLATE_BSLASH</constant>, <constant>EP_XLATE_EQUAL</constant>,
2660
    and <constant>EP_XLATE_PLUS</constant>. If none are listed,
2661
    <constant>EP_XLATE_PLUS</constant> is assumed.
2662
    <constant>EP_XLATE_8BIT</constant> can be added to encode all 8-bit
2663 b0136566 Eric Allman
    characters and <constant>EP_XLATE_NPRINT</constant> translates all
2664
    unprintable characters (as determined by <function>isprint(3)</function>,
2665
    which generally does understand locales). Returns the number of bytes
2666
    output to the indicated osp.</para>
2667 d63b8179 Eric Allman
2668
    <note>
2669
      <para>[[Arguably they should both use streams for both input and
2670
      output.]]</para>
2671
    </note>
2672
2673
    <para>There are also routines to encode/decode binaries in base64.</para>
2674
2675
    <programlisting>    #include &lt;ep/ep_b64.h&gt;
2676
2677
    EP_STAT
2678
    ep_b64_encode(
2679
        const void *bin,                // binary data to encode
2680
        size_t bsize,                   // size of bin to encode
2681
        char *txt,                      // text output buffer
2682
        size_t tsize,                   // size of output buffer
2683
        const char *encoding)           // type of encoding (see below)
2684
2685
    EP_STAT
2686
    ep_b64_decode(
2687
        const char *txt,                // text to decode
2688
        size_t tsize,                   // stop after tsize characters
2689
        void *bin,                      // binary output buffer
2690
        size_t bsize,                   // size of bin buffer
2691
        const char *encoding)           // type of encoding (see below)
2692
2693
    #define EP_B64_NOWRAP       0x00    // never wrap lines
2694
    #define EP_B64_WRAP64       0x01    // wrap at 64 characters
2695
    #define EP_B64_WRAP76       0x02    // wrap at 76 characters
2696
    #define EP_B64_WRAPMASK     0x03    // bit mask for wrapping
2697
    #define EP_B64_PAD          0x04    // pad with '='
2698
    #define EP_B64_IGNCRUD      0x08    // ignore unrecognized chars
2699
2700
    // encodings for common standards
2701
    #define EP_B64_ENC_MIME     "+/N"   // WRAP76  PAD  IGNCRUD
2702
    #define EP_B64_ENC_PEM      "+/E"   // WRAP64  PAD -IGNCRUD
2703
    #define EP_B64_ENC_URL      "-_@"   // NOWRAP -PAD -IGNCRUD</programlisting>
2704
2705
    <para>The encoding is a three character string. The first two characters
2706
    are used to represent the codes for positions 62 and 63 (these are the
2707
    only two that are not letters or digits). The third is used as flag bits
2708
    to indicate variations for various encodings. The three most common
2709
    strings are included as defined constants (for MIME email, Privacy
2710
    Enhanced Mail, and URLs).</para>
2711
  </section>
2712
2713
  <section>
2714
    <title>XXX TO BE DONE</title>
2715
2716
    <itemizedlist>
2717
      <listitem>
2718
        <para>Document ep_pprint.</para>
2719
      </listitem>
2720
2721
      <listitem>
2722
        <para>Document ep_dumpfds (shows open file descriptors (for
2723
        debugging).</para>
2724
      </listitem>
2725
2726
      <listitem>
2727
        <para>Document ep_fread_unlocked.</para>
2728
      </listitem>
2729
    </itemizedlist>
2730
  </section>
2731 11ef2ab4 Eric Allman
</article>