chiark / gitweb /
Various: Report errors encountered while doing channel I/O.
[fwd] / fwd.h
1 /* -*-c-*-
2  *
3  * Main header file for port forwarder
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of the `fwd' port forwarder.
11  *
12  * `fwd' is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * `fwd' is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with `fwd'; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 #ifndef FW_H
28 #define FW_H
29
30 #ifdef __cplusplus
31   extern "C" {
32 #endif
33
34 /*----- Header files ------------------------------------------------------*/
35
36 /* --- Configuration --- */
37
38 #include "config.h"
39 #define _GNU_SOURCE
40
41 /* --- ANSI C --- */
42
43 #include <assert.h>
44 #include <ctype.h>
45 #include <errno.h>
46 #include <float.h>
47 #include <limits.h>
48 #include <math.h>
49 #include <signal.h>
50 #include <stdarg.h>
51 #include <stddef.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <time.h>
56
57 /* --- Unix --- */
58
59 #include <fcntl.h>
60 #include <unistd.h>
61
62 #include <sys/types.h>
63 #include <sys/stat.h>
64 #include <sys/time.h>
65 #include <sys/uio.h>
66 #include <sys/wait.h>
67
68 #include <sys/socket.h>
69 #include <sys/un.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 #include <netdb.h>
73
74 #include <pwd.h>
75 #include <grp.h>
76
77 #include <syslog.h>
78
79 /* --- mLib --- */
80
81 #include <mLib/alloc.h>
82 #include <mLib/bres.h>
83 #include <mLib/conn.h>
84 #include <mLib/darray.h>
85 #include <mLib/dstr.h>
86 #include <mLib/env.h>
87 #include <mLib/fdflags.h>
88 #include <mLib/fdpass.h>
89 #include <mLib/ident.h>
90 #include <mLib/mdup.h>
91 #include <mLib/mdwopt.h>
92 #include <mLib/quis.h>
93 #include <mLib/report.h>
94 #include <mLib/sel.h>
95 #include <mLib/selbuf.h>
96 #include <mLib/sig.h>
97 #include <mLib/str.h>
98 #include <mLib/sub.h>
99 #include <mLib/sym.h>
100 #include <mLib/tv.h>
101
102 /*----- Other subtleties --------------------------------------------------*/
103
104 #if defined(HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
105   extern char **environ;
106 #endif
107
108 /*----- Main program ------------------------------------------------------*/
109
110 /* --- The global select state --- */
111
112 extern sel_state *sel;
113
114 /* --- Help text --- */
115
116 extern const char grammar_text[];
117 extern const char option_text[];
118
119 /* --- @fw_log@ --- *
120  *
121  * Arguments:   @time_t t@ = when the connection occurred or (@-1@)
122  *              @const char *fmt@ = format string to fill in
123  *              @...@ = other arguments
124  *
125  * Returns:     ---
126  *
127  * Use:         Logs a connection.
128  */
129
130 extern void fw_log(time_t /*t*/, const char */*fmt*/, ...);
131
132 /* --- @fw_inc@, @fw_dec@ --- *
133  *
134  * Arguments:   ---
135  *
136  * Returns:     ---
137  *
138  * Use:         Increments or decrements the active thing count.  `fwd' won't
139  *              quit while there are active things.
140  */
141
142 extern void fw_inc(void);
143 extern void fw_dec(void);
144
145 /*----- Channel management ------------------------------------------------*/
146
147 /* --- Magic numbers --- */
148
149 #define CHAN_BUFSZ 4096
150
151 /* --- Channel structure --- */
152
153 typedef struct chan {
154   unsigned base, len;                   /* Base and length of data */
155   unsigned f;                           /* Various interesting flags */
156   void (*func)(void */*p*/);            /* Function to call on closure */
157   int err;                              /* What's wrong with the channel */
158   void *p;                              /* Argument to pass function */
159   sel_file r, w;                        /* Reader and writer selectors */
160   char buf[CHAN_BUFSZ];                 /* The actual data buffer */
161 } chan;
162
163 #define CHANF_CLOSE 1u                  /* Close channel when buffer empty */
164 #define CHANF_READY 2u                  /* The channel destination exists */
165
166 /* --- @chan_close@ --- *
167  *
168  * Arguments:   @chan *c@ = pointer to channel
169  *
170  * Returns:     ---
171  *
172  * Use:         Closes down a channel prematurely.
173  */
174
175 extern void chan_close(chan */*c*/);
176
177 /* --- @chan_dest@ --- *
178  *
179  * Arguments:   @chan *c@ = pointer to channel
180  *              @int fd@ = destination file descriptor for channel
181  *
182  * Returns:     ---
183  *
184  * Use:         Sets the channel's destination so it knows where to put
185  *              data.
186  */
187
188 extern void chan_dest(chan */*c*/, int /*fd*/);
189
190 /* --- @chan_open@ --- *
191  *
192  * Arguments:   @chan *c@ = pointer to channel to open
193  *              @int from, to@ = source and destination file descriptors
194  *              @void (*func)(void *p)@ = function to call on closure
195  *              @void *p@ = argument to pass to function
196  *
197  * Returns:     ---
198  *
199  * Use:         Opens a channel.  Data is copied from the source to the
200  *              destination.  The @to@ argument may be @-1@ if the file
201  *              descriptor isn't known yet.
202  */
203
204 extern void chan_open(chan */*c*/, int /*from*/, int /*to*/,
205                       void (*/*func*/)(void */*p*/), void */*p*/);
206
207 /*----- Character scanners ------------------------------------------------*/
208
209 /* --- A low-level scanner source --- */
210
211 typedef struct scansrc {
212   struct scansrc *next;                 /* Next one in the list */
213   struct scansrc_ops *ops;              /* Pointer to operations table */
214   char *src;                            /* Name of this source */
215   int line;                             /* Current line number */
216   dstr pushback;                        /* Pushback characters */
217   char *tok;                            /* Token pushback */
218   unsigned t;                           /* Token type pushback */
219 } scansrc;
220
221 /* --- Scanner source operations --- */
222
223 typedef struct scansrc_ops {
224   int (*scan)(scansrc */*ss*/);         /* Read another character */
225   void (*destroy)(scansrc */*ss*/);     /* Destroy an unwanted source */
226 } scansrc_ops;
227
228 /* --- A character scanner --- */
229
230 typedef struct scanner {
231   scansrc *head, **tail;                /* Scanner list head and tail */
232   int t;                                /* Token type */
233   dstr d;                               /* Current token value */
234   const char *wbegin, *wcont;           /* Parsing exception strings */
235 } scanner;
236
237 /* --- @scan_file@ --- *
238  *
239  * Arguments:   @FILE *fp@ = pointer to file descriptor
240  *              @const char *name@ = pointer to source file name
241  *              @unsigned f@ = flags
242  *
243  * Returns:     A scanner source.
244  *
245  * Use:         Creates a new scanner source for reading from a file.
246  */
247
248 #define SCF_NOCLOSE 1u                  /* Don't close @fp@ when finished */
249
250 extern scansrc *scan_file(FILE */*fp*/, const char */*name*/,
251                           unsigned /*f*/);
252
253 /* --- @scan_argv@ --- *
254  *
255  * Arguments:   @char **av@ = pointer to argument array (null terminated)
256  *
257  * Returns:     A scanner source.
258  *
259  * Use:         Creates a new scanner source for reading from an @argv@
260  *              array.
261  */
262
263 extern scansrc *scan_argv(char **/*av*/);
264
265 /* --- @scan@ --- *
266  *
267  * Arguments:   @scanner *sc@ = pointer to main scanner context
268  *
269  * Returns:     Character read, or end-of-file.
270  *
271  * Use:         Scans a character from a source of characters.
272  */
273
274 extern int scan(scanner */*sc*/);
275
276 /* --- @unscan@ --- *
277  *
278  * Arguments:   @scanner *sc@ = pointer to main scanner context
279  *              @int ch@ = character to unscan
280  *
281  * Returns:     ---
282  *
283  * Use:         Scans a character from a source of characters.
284  */
285
286 extern void unscan(scanner */*sc*/, int /*ch*/);
287
288 /* --- @scan_push@ --- *
289  *
290  * Arguments:   @scanner *sc@ = pointer to main scanner context
291  *              @scansrc *ss@ = souorce to push
292  *
293  * Returns:     ---
294  *
295  * Use:         Pushes a scanner source onto the front of the queue.
296  */
297
298 extern void scan_push(scanner */*sc*/, scansrc */*ss*/);
299
300 /* --- @scan_add@ --- *
301  *
302  * Arguments:   @scanner *sc@ = pointer to main scanner context
303  *              @scansrc *ss@ = souorce to push
304  *
305  * Returns:     ---
306  *
307  * Use:         Adds a scanner source onto the end of the queue.
308  */
309
310 extern void scan_add(scanner */*sc*/, scansrc */*ss*/);
311
312 /* --- @scan_create@ --- *
313  *
314  * Arguments:   @scanner *sc@ = scanner context to initialize
315  *
316  * Returns:     ---
317  *
318  * Use:         Initializes a scanner block ready for use.
319  */
320
321 extern void scan_create(scanner */*sc*/);
322
323 /* --- @scan_destroy@ --- *
324  *
325  * Arguments:   @scanner *sc@ = pointer to scanner context
326  *
327  * Returns:     ---
328  *
329  * Use:         Destroys a scanner and all the sources attached to it.
330  */
331
332 extern void scan_destroy(scanner */*sc*/);
333
334 /*----- Configuration parsing ---------------------------------------------*/
335
336 /* --- Magical constants --- */
337
338 #define CTOK_EOF (-1)
339 #define CTOK_WORD 256
340
341 /* --- @conf_undelim@ --- *
342  *
343  * Arguments:   @scanner *sc@ = pointer to scanner definition
344  *              @const char *d, *dd@ = pointer to characters to escape
345  *
346  * Returns:     ---
347  *
348  * Use:         Modifies the tokenizer.  Characters in the first list will
349  *              always be considered to begin a word.  Characters in the
350  *              second list will always be allowed to continue a word.
351  */
352
353 extern void conf_undelim(scanner */*sc*/,
354                          const char */*d*/, const char */*dd*/);
355
356 /* --- @token@ --- *
357  *
358  * Arguments:   @scanner *sc@ = pointer to scanner definition
359  *
360  * Returns:     Type of token scanned.
361  *
362  * Use:         Reads the next token from the character scanner.
363  */
364
365 extern int token(scanner */*sc*/);
366
367 /* --- @error@ --- *
368  *
369  * Arguments:   @scanner *sc@ = pointer to scanner definition
370  *              @const char *msg@ = message skeleton string
371  *              @...@ = extra arguments for the skeleton
372  *
373  * Returns:     Doesn't
374  *
375  * Use:         Reports an error at the current scanner location.
376  */
377
378 extern void error(scanner */*sc*/, const char */*msg*/, ...);
379
380 /* --- @pushback@ --- *
381  *
382  * Arguments:   @scanner *sc@ = pointer to scanner definition
383  *
384  * Returns:     ---
385  *
386  * Use:         Pushes the current token back.  This is normally a precursor
387  *              to pushing a new scanner source.
388  */
389
390 extern void pushback(scanner */*sc*/);
391
392 /* --- @conf_enum@ --- *
393  *
394  * Arguments:   @scanner *sc@ = pointer to a scanner object
395  *              @const char *list@ = comma-separated things to allow
396  *              @unsigned @f = flags for the search
397  *              @const char *err@ = error message if not found
398  *
399  * Returns:     Index into list, zero-based, or @-1@.
400  *
401  * Use:         Checks whether the current token is a string which matches
402  *              one of the comma-separated items given.  The return value is
403  *              the index (zero-based) of the matched string in the list.
404  *
405  *              The flags control the behaviour if no exact match is found.
406  *              If @ENUM_ABBREV@ is set, and the current token is a left
407  *              substring of exactly one of the possibilities, then that one
408  *              is chosen.  If @ENUM_NONE@ is set, the value @-1@ is
409  *              returned; otherwise an error is reported and the program is
410  *              terminated.
411  */
412
413 #define ENUM_ABBREV 1u
414 #define ENUM_NONE 2u
415
416 extern int conf_enum(scanner */*sc*/, const char */*list*/,
417                      unsigned /*flags*/, const char */*err*/);
418
419 /* --- @conf_prefix@ --- *
420  *
421  * Arguments:   @scanner *sc@ = pointer to a scanner object
422  *              @const char *p@ = pointer to prefix string to check
423  *
424  * Returns:     Nonzero if the prefix matches.
425  *
426  * Use:         If the current token is a word matching the given prefix
427  *              string, then it and an optional `.' character are removed and
428  *              a nonzero result is returned.  Otherwise the current token is
429  *              left as it is, and zero is returned.
430  *
431  *              Typical options parsing code would remove an expected prefix,
432  *              scan an option anyway (since qualifying prefixes are
433  *              optional) and if a match is found, claim the option.  If no
434  *              match is found, and a prefix was stripped, then an error
435  *              should be reported.
436  */
437
438 extern int conf_prefix(scanner */*sc*/, const char */*p*/);
439
440 /* --- @CONF_BEGIN@, @CONF_END@ --- *
441  *
442  * Arguments:   @sc@ = scanner to read from
443  *              @prefix@ = prefix to scan for
444  *              @desc@ = description of what we're parsing
445  *
446  * Use:         Bracket an options parsing routine.  The current token is
447  *              checked to see whether it matches the prefix.  If so, it is
448  *              removed and the following token examined.  If that's a `.'
449  *              then it's removed.  If it's a `{' then the enclosed
450  *              option-parsing code is executed in a loop until a matching
451  *              '}' is found.  If the options parser doesn't accept an
452  *              option, the behaviour is dependent on whether a prefix was
453  *              seen: if so, an error is reported; otherwse a zero return is
454  *              made.
455  */
456
457 #define CS_PLAIN 0
458 #define CS_PREFIX 1
459 #define CS_BRACE 2
460 #define CS_UNKNOWN 3
461
462 #define CONF_BEGIN(sc, prefix, desc) do {                               \
463   scanner *_conf_sc = (sc);                                             \
464   const char *_conf_desc = (desc);                                      \
465   int _conf_state = CS_PLAIN;                                           \
466                                                                         \
467   /* --- Read the initial prefix --- */                                 \
468                                                                         \
469   if (_conf_sc->t == CTOK_WORD &&                                       \
470       strcmp(_conf_sc->d.buf, (prefix)) == 0) {                         \
471     token(_conf_sc);                                                    \
472     _conf_state = CS_PREFIX;                                            \
473     if (_conf_sc->t == '.')                                             \
474       token(_conf_sc);                                                  \
475     else if (_conf_sc->t == '{') {                                      \
476       token(_conf_sc);                                                  \
477       _conf_state = CS_BRACE;                                           \
478     }                                                                   \
479   }                                                                     \
480                                                                         \
481   /* --- Ensure the next token is a word --- */                         \
482                                                                         \
483   if (_conf_sc->t != CTOK_WORD)                                         \
484     error(_conf_sc, "parse error, expected option keyword");            \
485   do {
486
487 #define CONF_END                                                        \
488                                                                         \
489     /* --- Reject an option --- *                                       \
490      *                                                                  \
491      * We could get here as a result of an explicit @CONF_REJECT@ or    \
492      * because the option wasn't accepted.                              \
493      */                                                                 \
494                                                                         \
495     goto _conf_reject;                                                  \
496   _conf_reject:                                                         \
497     if (_conf_state == CS_PLAIN)                                        \
498       _conf_state = CS_UNKNOWN;                                         \
499     else {                                                              \
500       error(_conf_sc, "unknown %s option `%s'",                         \
501             _conf_desc, _conf_sc->d.buf);                               \
502     }                                                                   \
503                                                                         \
504     /* --- Accept an option --- *                                       \
505      *                                                                  \
506      * It's safe to drop through from above.  Either an error will have \
507      * been reported, or the state is not @CS_BRACE@.                   \
508      */                                                                 \
509                                                                         \
510   _conf_accept:                                                         \
511     if (_conf_state == CS_BRACE && _conf_sc->t == ';')                  \
512       token(_conf_sc);                                                  \
513   } while (_conf_state == CS_BRACE && _conf_sc->t == CTOK_WORD);        \
514                                                                         \
515   /* --- Check for a closing brace --- */                               \
516                                                                         \
517   if (_conf_state == CS_BRACE) {                                        \
518     if (_conf_sc->t == '}')                                             \
519       token(_conf_sc);                                                  \
520     else                                                                \
521       error(_conf_sc, "parse error, expected `}'");                     \
522   }                                                                     \
523                                                                         \
524   /* --- Return an appropriate value --- */                             \
525                                                                         \
526   return (_conf_state != CS_UNKNOWN);                                   \
527 } while (0)
528
529 /* --- @CONF_ACCEPT@, @CONF_REJECT@ --- *
530  *
531  * Arguments:   ---
532  *
533  * Use:         Within an options parser (between @CONF_BEGIN@ and
534  *              @CONF_END@), accept or reject an option.
535  */
536
537 #define CONF_ACCEPT goto _conf_accept
538 #define CONF_REJECT goto _conf_reject
539
540 /* --- @CONF_QUAL@ --- *
541  *
542  * Arguments:   ---
543  *
544  * Use:         Evaluates to a nonzero value if the current option is
545  *              qualified.  This can be used to decide whether abbreviations
546  *              for options should be accepted.
547  */
548
549 #define CONF_QUAL (_conf_state != CS_PLAIN)
550
551 /* --- @conf_name@ --- *
552  *
553  * Arguments:   @scanner *sc@ = pointer to scanner
554  *              @char delim@ = delimiter character to look for
555  *              @dstr *d@ = pointer to dynamic string for output
556  *
557  * Returns:     ---
558  *
559  * Use:         Reads in a compound name consisting of words separated by
560  *              delimiters.  Leading and trailing delimiters are permitted,
561  *              although they'll probably cause confusion if used.  The name
562  *              may be enclosed in square brackets if that helps at all.
563  *
564  *              Examples of compound names are filenames (delimited by `/')
565  *              and IP addresses (delimited by `.').
566  */
567
568 extern void conf_name(scanner */*sc*/, char /*delim*/, dstr */*d*/);
569
570 /* --- @conf_fname@ --- *
571  *
572  * Arguments:   @scanner *sc@ = pointer to scanner
573  *              @dstr *d@ = pointer to dynamic string for output
574  *
575  * Returns:     ---
576  *
577  * Use:         Reads a file name from the input and stores it in @d@.
578  */
579
580 extern void conf_fname(scanner */*sc*/, dstr */*d*/);
581
582 /*----- Reference-counted file descriptors --------------------------------*/
583
584 typedef struct reffd {
585   int fd;
586   unsigned ref;
587   void (*proc)(void */*p*/);
588   void *p;
589 } reffd;
590
591 /* --- @reffd_init@ --- *
592  *
593  * Arguments:   @int fd@ = file descriptor
594  *
595  * Returns:     Reference-counted file descriptor object.
596  *
597  * Use:         Creates a refcounted file descriptor.
598  */
599
600 extern reffd *reffd_init(int /*fd*/);
601
602 /* --- @reffd_handler@ --- *
603  *
604  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
605  *              @void (*proc)(void *p)@ = procedure to call
606  *              @void *p@
607  *
608  * Returns:     ---
609  *
610  * Use:         Sets the reference counted file descriptor to call @proc@
611  *              when it is no longer required.
612  */
613
614 extern void reffd_handler(reffd */*r*/, void (*/*proc*/)(void */*p*/),
615                           void */*p*/);
616
617 /* --- @reffd_inc@ --- *
618  *
619  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
620  *
621  * Returns:     ---
622  *
623  * Use:         Increments the reference count for a file descriptor.
624  */
625
626 #define REFFD_INC(r) do { (r)->ref++; } while (0)
627
628 extern void reffd_inc(reffd */*r*/);
629
630 /* --- @reffd_dec@ --- *
631  *
632  * Arguments:   @reffd *r@ = pointer to reference counted filehandle
633  *
634  * Returns:     ---
635  *
636  * Use:         Decrements the reference count for a file descriptor.
637  */
638
639 #define REFFD_DEC(r) do {                                               \
640   reffd *_r = (r);                                                      \
641   _r->ref--;                                                            \
642   if (_r->ref == 0) {                                                   \
643     close(_r->fd);                                                      \
644     if (_r->proc)                                                       \
645       _r->proc(_r->p);                                                  \
646     DESTROY(_r);                                                        \
647   }                                                                     \
648 } while (0)
649
650 extern void reffd_dec(reffd */*r*/);
651
652 /*----- Sources, targets and endpoints ------------------------------------*/
653
654 /* --- Basic endpoint structure --- */
655
656 typedef struct endpt {
657   struct endpt_ops *ops;                /* Pointer to operations table */
658   struct endpt *other;                  /* Pointer to sibling endpoint */
659   unsigned f;                           /* Various flags */
660   struct tango *t;                      /* Private data structure */
661   reffd *in, *out;                      /* File descriptors */
662 } endpt;
663
664 /* --- Endpoint flags --- */
665
666 #define EPF_PENDING 1u                  /* Endpoint creation in progress */
667 #define EPF_FILE 2u                     /* Endpoint smells like a file */
668
669 /* --- Endpoint operations table --- */
670
671 typedef struct endpt_ops {
672
673   /* --- @attach@ --- *
674    *
675    * Arguments: @endpt *e@ = pointer to endpoint to be attached
676    *            @reffd *in, *out@ = input and output file descriptors
677    *
678    * Returns:   ---
679    *
680    * Use:       Instructs a non-file endpoint to attach itself to a pair of
681    *            files.
682    */
683
684   void (*attach)(endpt */*e*/, reffd */*in*/, reffd */*out*/);
685
686   /* --- @file@ --- *
687    *
688    * Arguments: @endpt *e@ = pointer to endpoint in question
689    *            @endpt *f@ = pointer to a file endpoint
690    *
691    * Returns:   ---
692    *
693    * Use:       Informs a non-file endpoint of a file endpoint which will
694    *            want to be closed when it's finished with.  At that time, the
695    *            endpoint should arrange to have both itself and its partner
696    *            closed.  If no file is registered, the endpoint manager will
697    *            close both endpoints itself.
698    */
699
700   void (*file)(endpt */*e*/, endpt */*f*/);
701
702   /* --- @wclose@ --- *
703    *
704    * Arguments: @endpt *e@ = endpoint to be partially closed
705    *
706    * Returns:   ---
707    *
708    * Use:       Announces that the endpoint will not be written to any more.
709    */
710
711   void (*wclose)(endpt */*e*/);
712
713   /* --- @close@ --- *
714    *
715    * Arguments: @endpt *e@ = endpoint to be closed
716    *
717    * Returns:   ---
718    *
719    * Use:       Completely closes an endpoint.  The endpoint's data may be
720    *            freed, although some endpoints may wish to delay freeing for
721    *            some reason.
722    */
723
724   void (*close)(endpt */*e*/);
725
726 } endpt_ops;
727
728 /* --- A basic target object --- */
729
730 typedef struct target {
731   struct target_ops *ops;
732   char *desc;
733 } target;
734
735 /* --- Forwarding target operations --- */
736
737 typedef struct target_ops {
738   const char *name;                     /* Name of this target */
739
740   /* --- @option@ --- *
741    *
742    * Arguments: @target *t@ = pointer to target object, or zero if global
743    *            @scanner *sc@ = scanner to read from
744    *
745    * Returns:   Nonzero to claim the option.
746    *
747    * Use:       Handles an option string from the configuration file.
748    */
749
750   int (*option)(target */*t*/, scanner */*sc*/);
751
752   /* --- @read@ --- *
753    *
754    * Arguments: @scanner *sc@ = pointer to scanner to read from
755    *
756    * Returns:   Pointer to a target object to claim, null to reject.
757    *
758    * Use:       Parses a target description from the configuration file.
759    *            Only the socket target is allowed to omit the prefix on a
760    *            target specification.
761    */
762
763   target *(*read)(scanner */*sc*/);
764
765   /* --- @confirm@ --- *
766    *
767    * Arguments: @target *t@ = pointer to target
768    *
769    * Returns:   ---
770    *
771    * Use:       Confirms configuration of a target.
772    */
773
774   void (*confirm)(target */*t*/);
775
776   /* --- @create@ --- *
777    *
778    * Arguments: @target *t@ = pointer to target
779    *            @const char *desc@ = description of connection
780    *
781    * Returns:   Pointer to a created endpoint.
782    *
783    * Use:       Generates a target endpoint for communication.
784    */
785
786   endpt *(*create)(target */*t*/, const char */*desc*/);
787
788   /* --- @destroy@ --- *
789    *
790    * Arguments: @target *t@ = pointer to target
791    *
792    * Returns:   ---
793    *
794    * Use:       Destroys a target.
795    */
796
797   void (*destroy)(target */*t*/);
798
799 } target_ops;
800
801 /* --- A basic source object --- */
802
803 typedef struct source {
804   struct source *next, *prev;
805   struct source_ops *ops;
806   char *desc;
807 } source;
808
809 /* --- Forwarding source operations --- */
810
811 typedef struct source_ops {
812   const char *name;                     /* Name of this source */
813
814   /* --- @option@ --- *
815    *
816    * Arguments: @scanner *sc@ = scanner to read from
817    *            @source *s@ = pointer to source object, or zero if global
818    *
819    * Returns:   Nonzero to claim the option.
820    *
821    * Use:       Handles an option string from the configuration file.
822    */
823
824   int (*option)(source */*s*/, scanner */*sc*/);
825
826   /* --- @read@ --- *
827    *
828    * Arguments: @scanner *sc@ = pointer to scanner to read from
829    *
830    * Returns:   Pointer to a source object to claim, null to reject.
831    *
832    * Use:       Parses a source description from the configuration file.
833    *            Only the socket source is allowed to omit the prefix on a
834    *            source specification.
835    */
836
837   source *(*read)(scanner */*sc*/);
838
839   /* --- @attach@ --- *
840    *
841    * Arguments: @source *s@ = pointer to source
842    *            @scanner *sc@ = scanner (for error reporting)
843    *            @target *t@ = pointer to target to attach
844    *
845    * Returns:   ---
846    *
847    * Use:       Attaches a target to a source.
848    */
849
850   void (*attach)(source */*s*/, scanner */*sc*/, target */*t*/);
851
852   /* --- @destroy@ --- *
853    *
854    * Arguments: @source *s@ = pointer to source
855    *
856    * Returns:   ---
857    *
858    * Use:       Destroys a source.  Used when closing the system down, for
859    *            example as a result of a signal.
860    */
861
862   void (*destroy)(source */*s*/);
863
864 } source_ops;
865
866 /* --- @endpt_kill@ --- *
867  *
868  * Arguments:   @endpt *a@ = an endpoint
869  *
870  * Returns:     ---
871  *
872  * Use:         Kills an endpoint.  If the endpoint is joined to another, the
873  *              other endpoint is also killed, as is the connection between
874  *              them (and that's the tricky bit).
875  */
876
877 extern void endpt_kill(endpt */*a*/);
878
879 /* --- @endpt_killall@ --- *
880  *
881  * Arguments:   ---
882  *
883  * Returns:     ---
884  *
885  * Use:         Destroys all current endpoint connections.  Used when
886  *              shutting down.
887  */
888
889 extern void endpt_killall(void);
890
891 /* --- @endpt_join@ --- *
892  *
893  * Arguments:   @endpt *a@ = pointer to first endpoint
894  *              @endpt *b@ = pointer to second endpoint
895  *              @const char *desc@ = description of connection
896  *
897  * Returns:     ---
898  *
899  * Use:         Joins two endpoints together.  It's OK to join endpoints
900  *              which are already joined; in fact, the the right thing to do
901  *              when your endpoint decides that it's not pending any more is
902  *              to join it to its partner again.
903  *
904  *              If the endpoints are already connected then the description
905  *              string is ignored.  The endpoint manager takes a copy of
906  *              the string, so you don't need to keep it around.
907  */
908
909 extern void endpt_join(endpt */*a*/, endpt */*b*/, const char */*desc*/);
910
911 /* --- @source_add@ --- *
912  *
913  * Arguments:   @source *s@ = pointer to a source
914  *
915  * Returns:     ---
916  *
917  * Use:         Adds a source to the master list.  Only do this for passive
918  *              sources (e.g., listening sockets), not active sources (e.g.,
919  *              executable programs).
920  */
921
922 extern void source_add(source */*s*/);
923
924 /* --- @source_remove@ --- *
925  *
926  * Arguments:   @source *s@ = pointer to a source
927  *
928  * Returns:     ---
929  *
930  * Use:         Removes a source from the master list.
931  */
932
933 extern void source_remove(source */*s*/);
934
935 /* --- @source_killall@ --- *
936  *
937  * Arguments:   ---
938  *
939  * Returns:     ---
940  *
941  * Use:         Frees all sources.
942  */
943
944 extern void source_killall(void);
945
946 /*----- The exec source and target ----------------------------------------*/
947
948 extern source_ops xsource_ops;
949 extern target_ops xtarget_ops;
950
951 /* --- @exec_init@ --- *
952  *
953  * Arguments:   ---
954  *
955  * Returns:     ---
956  *
957  * Use:         Initializes the executable problem source and target.
958  */
959
960 extern void exec_init(void);
961
962 /*----- The file source and target ----------------------------------------*/
963
964 extern source_ops fsource_ops;
965 extern target_ops ftarget_ops;
966
967 /*----- The socket source and target --------------------------------------*/
968
969 extern source_ops ssource_ops;
970 extern target_ops starget_ops;
971
972 /* --- @starget_connected@ --- *
973  *
974  * Arguments:   @int fd@ = file descriptor now ready for use
975  *              @void *p@ = pointer to an endpoint structure
976  *
977  * Returns:     ---
978  *
979  * Use:         Handles successful connection of the target endpoint.
980  */
981
982 extern void starget_connected(int /*fd*/, void */*p*/);
983
984 /*----- Handling of file attributes ---------------------------------------*/
985
986 /* --- File attribute options structure --- */
987
988 typedef struct fattr {
989   unsigned mode;
990   uid_t uid;
991   gid_t gid;
992 } fattr;
993
994 /* --- Shared global options --- */
995
996 extern fattr fattr_global;
997
998 /* --- @fattr_init@ --- *
999  *
1000  * Arguments:   @fattr *f@ = pointer to file attributes
1001  *
1002  * Returns:     ---
1003  *
1004  * Use:         Initializes a set of file attributes to default values.
1005  */
1006
1007 extern void fattr_init(fattr */*f*/);
1008
1009 /* --- @fattr_option@ --- *
1010  *
1011  * Arguments:   @scanner *sc@ = pointer to scanner to read
1012  *              @fattr *f@ = pointer to file attributes to set
1013  *
1014  * Returns:     Whether the option was clamed.
1015  *
1016  * Use:         Reads file attributes from a scanner.
1017  */
1018
1019 extern int fattr_option(scanner */*sc*/, fattr */*f*/);
1020
1021 /* --- @fattr_apply@ --- *
1022  *
1023  * Arguments:   @const char *file@ = pointer to filename
1024  *              @fattr *f@ = pointer to attribute set
1025  *
1026  * Returns:     @-1@ if it failed.
1027  *
1028  * Use:         Applies file attributes to a file.  For best results, try to
1029  *              create the file with the right permissions and so on.  This
1030  *              call will fix everything up, but there are potential races
1031  *              which might catch you out if you're not careful.
1032  */
1033
1034 extern int fattr_apply(const char */*file*/, fattr */*f*/);
1035
1036 /*----- Making privileged connections -------------------------------------*/
1037
1038 /* --- @privconn_split@ --- *
1039  *
1040  * Arguments:   @sel_state *s@ = select state
1041  *
1042  * Returns:     ---
1043  *
1044  * Use:         Splits off the privileged binding code into a separate
1045  *              process.
1046  */
1047
1048 extern void privconn_split(sel_state */*s*/);
1049
1050 /* --- @privconn_adddest@ --- *
1051  *
1052  * Arguments:   @struct in_addr peer@ = address to connect to
1053  *              @unsigned port@ = port to connect to
1054  *
1055  * Returns:     Index for this destination address, or @-1@ if not
1056  *              available.
1057  *
1058  * Use:         Adds a valid destination for a privileged connection.
1059  */
1060
1061 extern int privconn_adddest(struct in_addr /*peer*/, unsigned /*port*/);
1062
1063 /* --- @privconn_connect@ --- *
1064  *
1065  * Arguments:   @conn *c@ = connection structure to fill in
1066  *              @sel_state *s@ = pointer to select state to attach to
1067  *              @int i@ = address index to connect to
1068  *              @struct in_addr bind@ = address to bind to
1069  *              @void (*func)(int, void *)@ = function to call on connect
1070  *              @void *p@ = argument for the function
1071  *
1072  * Returns:     Zero on success, @-1@ on failure.
1073  *
1074  * Use:         Sets up a privileged connection job.
1075  */
1076
1077 extern int privconn_connect(conn */*c*/, sel_state */*s*/,
1078                             int /*i*/, struct in_addr /*bind*/,
1079                             void (*/*func*/)(int, void *), void */*p*/);
1080
1081 /*----- Identifying remote clients ----------------------------------------*/
1082
1083 typedef struct id_req {
1084   struct sockaddr_in lsin;              /* Local address of connection */
1085   struct sockaddr_in rsin;              /* Remote address of connection */
1086   const char *desc;                     /* Description of connection */
1087   const char *act;                      /* Action taken by server */
1088   reffd *r;                             /* Pointer to file descriptor */
1089 } id_req;
1090
1091 /* --- @identify@ --- *
1092  *
1093  * Arguments:   @const id_req *q@ = pointer to request block
1094  *
1095  * Returns:     ---
1096  *
1097  * Use:         Starts a background ident lookup and reverse-resolve job
1098  *              which will, eventually, report a message to the system log.
1099  */
1100
1101 extern void identify(const id_req */*q*/);
1102
1103 /*----- Host-based access control -----------------------------------------*/
1104
1105 /* --- An access control entry --- */
1106
1107 typedef struct acl_entry {
1108   struct acl_entry *next;               /* Next entry in the list */
1109   const struct acl_ops *ops;            /* Operations for the ACL entry */
1110   unsigned act;                         /* What to do with matching hosts */
1111 } acl_entry;
1112
1113 #define ACL_DENY 0                      /* Deny access to matching conns */
1114 #define ACL_ALLOW 1                     /* Allow access to matching conns */
1115 #define ACL_PERM 1u                     /* Bit mask for permission bit */
1116
1117 /* --- Host-based access control --- */
1118
1119 typedef struct acl_host {
1120   acl_entry a;                          /* Base structure */
1121   struct in_addr addr, mask;            /* Address and netmask */
1122 } acl_host;
1123
1124 /* --- ACL methods --- */
1125
1126 typedef struct acl_ops {
1127   int (*check)(void */*a*/, struct in_addr /*addr*/, unsigned /*port*/);
1128   void (*dump)(void */*a*/, FILE */*fp*/);
1129   void (*free)(void */*a*/);
1130 } acl_ops;
1131
1132 /* --- @acl_check@ --- *
1133  *
1134  * Arguments:   @acl_entry *a@ = pointer to ACL to check against
1135  *              @struct in_addr addr@ = address to check
1136  *              @unsigned port@ = port number to check
1137  *              @int *act@ = verdict (should initially be @ACT_ALLOW@)
1138  *
1139  * Returns:     Zero if undecided, nonzero if a rule matched.
1140  *
1141  * Use:         Checks an address against an ACL.
1142  */
1143
1144 extern int acl_check(acl_entry */*a*/,
1145                      struct in_addr /*addr*/, unsigned /*port*/,
1146                      int */*act*/);
1147
1148 /* --- @acl_dump@ --- *
1149  *
1150  * Arguments:   @acl_entry *a@ = pointer to ACL to dump
1151  *              @FILE *fp@ = pointer to stream to dump on
1152  *
1153  * Returns:     ---
1154  *
1155  * Use:         Dumps an access control list to an output stream.
1156  */
1157
1158 extern void acl_dump(acl_entry */*a*/, FILE */*fp*/);
1159
1160 /* --- @acl_free@ --- *
1161  *
1162  * Arguments:   @acl_entry *a@ = pointer to a list of ACLs
1163  *
1164  * Returns:     ---
1165  *
1166  * Use:         Frees all of the memory used by an ACL.
1167  */
1168
1169 extern void acl_free(acl_entry */*a*/);
1170
1171 /* --- @acl_addhost@ --- *
1172  *
1173  * Arguments:   @acl_entry ***a@ = address of pointer to list tail
1174  *              @unsigned act@ = what to do with matching addresses
1175  *              @struct in_addr addr, mask@ = address and mask to match
1176  *
1177  * Returns:     ---
1178  *
1179  * Use:         Adds a host-authentication entry to the end of an access
1180  *              control list.
1181  */
1182
1183 extern void acl_addhost(acl_entry ***/*a*/, unsigned /*act*/,
1184                         struct in_addr /*addr*/, struct in_addr /*mask*/);
1185
1186 /* --- @acl_addpriv@ --- *
1187  *
1188  * Arguments:   @acl_entry ***a@ = address of pointer to list tail
1189  *              @unsigned act@ = what to do with matching addresses
1190  *
1191  * Returns:     ---
1192  *
1193  * Use:         Adds a privileged-port check to the end of an access control
1194  *              list.
1195  */
1196
1197 extern void acl_addpriv(acl_entry ***/*a*/, unsigned /*act*/);
1198
1199 /*----- Network addresses -------------------------------------------------*/
1200
1201 /* --- A generic socket address --- *
1202  *
1203  * Not all systems understand @sa_len@ fields.  (In particular, Linux
1204  * doesn't.)  Some fairly ugly hacking is then performed on particular
1205  * address types.
1206  */
1207
1208 typedef struct addr {
1209   struct addr_ops *ops;
1210   size_t sz;
1211 } addr;
1212
1213 #define ADDRSZ(sz) (sizeof(addr) + (sz))
1214
1215 /* --- Address configuration --- *
1216  *
1217  * An address family will want to extend this.
1218  */
1219
1220 typedef struct addr_opts {
1221   unsigned f;
1222 } addr_opts;
1223
1224 #define ADDRF_NOLOG 1u
1225
1226 /* --- Address types --- *
1227  *
1228  * For things like Internet addresses, source and destinations look
1229  * different.
1230  */
1231
1232 enum {
1233   ADDR_SRC,
1234   ADDR_DEST,
1235   ADDR_GLOBAL
1236 };
1237
1238 /* --- Description of an address type handler --- */
1239
1240 typedef struct addr_ops {
1241   const char *name;                     /* Protocol's internal name */
1242
1243   /* --- @read@ --- *
1244    *
1245    * Arguments: @scanner *sc@ = pointer to scanner to read from
1246    *            @unsigned type@ = type of address to be read
1247    *
1248    * Returns:   A filled-in socket address.
1249    *
1250    * Use:       Parses a textual representation of a socket address.
1251    */
1252
1253   addr *(*read)(scanner */*sc*/, unsigned /*type*/);
1254
1255   /* --- @destroy@ --- *
1256    *
1257    * Arguments: @addr *a@ = pointer to an address block
1258    *
1259    * Returns:   ---
1260    *
1261    * Use:       Disposes of an address block in some suitable fashion.
1262    */
1263
1264   void (*destroy)(addr */*a*/);
1265
1266   /* --- @print@ --- *
1267    *
1268    * Arguments: @addr *a@ = pointer to socket address to read
1269    *            @unsigned type@ = type of address to be written
1270    *            @dstr *d@ = string on which to write the description
1271    *
1272    * Returns:   ---
1273    *
1274    * Use:       Writes a textual representation of a socket address to
1275    *            a string.
1276    */
1277
1278   void (*print)(addr */*a*/, unsigned /*type*/, dstr */*d*/);
1279
1280   /* --- @initsrcopts@ --- *
1281    *
1282    * Arguments: ---
1283    *
1284    * Returns:   A pointer to a protocol-specific data block for a listener
1285    *
1286    * Use:       Creates a data block for a listener.  This is attached to the
1287    *            listener data structure.  Options can then be requested, and
1288    *            are added to the block when necessary.
1289    */
1290
1291   addr_opts *(*initsrcopts)(void);
1292
1293   /* --- @option@ --- *
1294    *
1295    * Arguments: @scanner *sc@ = pointer to a scanner to read from
1296    *            @unsigned type@ = kind of option this is
1297    *            @addr_opts *ao@ = data block to modify (from @init@), or null
1298    *
1299    * Returns:   Nonzero to claim the option.
1300    *
1301    * Use:       Parses a source option, either global or listener-specific.
1302    */
1303
1304   int (*option)(scanner */*sc*/, addr_opts */*ao*/, unsigned /*type*/);
1305
1306   /* --- @confirm@ --- *
1307    *
1308    * Arguments: @addr *a@ = pointer to an address structure
1309    *            @unsigned type@ = kind of address this is
1310    *            @addr_opts *ao@ = address options
1311    *
1312    * Returns:   ---
1313    *
1314    * Use:       Called during initialization when an address is fully
1315    *            configured.
1316    */
1317
1318   void (*confirm)(addr */*a*/, unsigned /*type*/, addr_opts */*ao*/);
1319
1320   /* --- @freesrcopts@ --- *
1321    *
1322    * Arguments: @addr_opts *ao@ = data block to remove
1323    *
1324    * Returns:   ---
1325    *
1326    * Use:       Throws away all the configuration data for an address type.
1327    */
1328
1329   void (*freesrcopts)(addr_opts */*ao*/);
1330
1331   /* --- @bind@ --- *
1332    *
1333    * Arguments: @addr *a@ = the address to bind to
1334    *            @addr_opts *ao@ = the address options
1335    *
1336    * Returns:   File descriptor of bound socket if OK, or @-1@ on error.
1337    *
1338    * Use:       Binds a listening socket.  The tedious stuff with @listen@
1339    *            isn't necessary.
1340    */
1341
1342   int (*bind)(addr */*a*/, addr_opts */*ao*/);
1343
1344   /* --- @unbind@ --- *
1345    *
1346    * Arguments: @addr *a@ = pointer to an address
1347    *
1348    * Returns:   ---
1349    *
1350    * Use:       Unbinds an address.  This is used when tidying up.  The main
1351    *            purpose is to let the Unix-domain handler remove its socket
1352    *            node from the filesystem.
1353    */
1354
1355   void (*unbind)(addr */*a*/);
1356
1357   /* --- @accept@ --- *
1358    *
1359    * Arguments: @int fd@ = listening file descriptor
1360    *            @addr_opts *ao@ = data block to get configuration from
1361    *            @const char *desc@ = description of the listener
1362    *
1363    * Returns:   Pointer to a reference counted file descriptor.
1364    *
1365    * Use:       Accepts, verifies and logs an incoming connection.
1366    */
1367
1368   reffd *(*accept)(int /*fd*/, addr_opts */*ao*/, const char */*desc*/);
1369
1370   /* --- @inittargopts@ --- *
1371    *
1372    * Arguments: ---
1373    *
1374    * Returns:   A pointer to a protocol-specific data block for a connecter
1375    *
1376    * Use:       Creates a data block for a target.  This is attached to the
1377    *            target data structure.  Options can then be requested, and
1378    *            are added to the block when necessary.
1379    */
1380
1381   addr_opts *(*inittargopts)(void);
1382
1383   /* --- @freetargopts@ --- *
1384    *
1385    * Arguments: @addr_opts *ao@ = data block to remove
1386    *
1387    * Returns:   ---
1388    *
1389    * Use:       Throws away all the configuration data for an address type.
1390    */
1391
1392   void (*freetargopts)(addr_opts */*ao*/);
1393
1394   /* --- @connect@ --- *
1395    *
1396    * Arguments: @addr *a@ = destination address
1397    *            @addr_opts *ao@ = target address options
1398    *            @conn *c@ = connection structure
1399    *            @endpt *e@ = endpoint structure
1400    *
1401    * Returns:   Zero if OK, @-1@ on some error.
1402    *
1403    * Use:       Requests that a connection be made, or at least set in
1404    *            motion.  An address may do one of these things:
1405    *
1406    *              * Return @-1@.
1407    *
1408    *              * Call @starget_connected@ with @-1@ or a connected file
1409    *                descriptor and the pointer @e@.
1410    *
1411    *              * Call @conn_init@ or @conn_fd@, giving @starget_connected@
1412    *                and @e@ as the function to call.
1413    */
1414
1415   int (*connect)(addr */*a*/, addr_opts */*ao*/, conn */*c*/, endpt */*e*/);
1416
1417 } addr_ops;
1418
1419 /* --- Address types --- */
1420
1421 extern addr_ops un_ops;
1422 extern addr_ops inet_ops;
1423
1424 /*----- That's all, folks -------------------------------------------------*/
1425
1426 #ifdef __cplusplus
1427   }
1428 #endif
1429
1430 #endif