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