diff options
Diffstat (limited to 'man')
-rw-r--r-- | man/INSTALL | 12 | ||||
-rw-r--r-- | man/alloc.3 | 68 | ||||
-rw-r--r-- | man/buffer.3 | 185 | ||||
-rw-r--r-- | man/byte.3 | 82 | ||||
-rw-r--r-- | man/case.3 | 124 | ||||
-rw-r--r-- | man/cdbmake.3 | 61 | ||||
-rw-r--r-- | man/cdbread.3 | 177 | ||||
-rw-r--r-- | man/constmap.3 | 56 | ||||
-rw-r--r-- | man/dns.3 | 249 | ||||
-rw-r--r-- | man/dnsstub.3 | 109 | ||||
-rw-r--r-- | man/env.3 | 68 | ||||
-rw-r--r-- | man/error.3 | 75 | ||||
-rw-r--r-- | man/fd.3 | 79 | ||||
-rw-r--r-- | man/fmt.3 | 90 | ||||
-rw-r--r-- | man/getln.3 | 102 | ||||
-rw-r--r-- | man/getoptb.3 | 22 | ||||
-rw-r--r-- | man/iopause.3 | 87 | ||||
-rw-r--r-- | man/ip4.3 | 73 | ||||
-rw-r--r-- | man/ip6.3 | 98 | ||||
-rw-r--r-- | man/logmsg.3 | 109 | ||||
-rw-r--r-- | man/pathexec.3 | 124 | ||||
-rw-r--r-- | man/scan.3 | 81 | ||||
-rw-r--r-- | man/socket_bind.3 | 117 | ||||
-rw-r--r-- | man/socket_connect.3 | 110 | ||||
-rw-r--r-- | man/socket_if.3 | 97 | ||||
-rw-r--r-- | man/socket_info.3 | 47 | ||||
-rw-r--r-- | man/socket_recv.3 | 56 | ||||
-rw-r--r-- | man/socket_send.3 | 76 | ||||
-rw-r--r-- | man/socket_setup.3 | 105 | ||||
-rw-r--r-- | man/socket_tcp.3 | 58 | ||||
-rw-r--r-- | man/socket_udp.3 | 58 | ||||
-rw-r--r-- | man/str.3 | 61 | ||||
-rw-r--r-- | man/stralloc.3 | 160 | ||||
-rw-r--r-- | man/taia.3 | 91 | ||||
-rw-r--r-- | man/timeout.3 | 36 | ||||
-rw-r--r-- | man/timeoutconn.3 | 52 | ||||
-rw-r--r-- | man/wait.3 | 96 | ||||
-rw-r--r-- | man/x.html | 99 |
38 files changed, 3450 insertions, 0 deletions
diff --git a/man/INSTALL b/man/INSTALL new file mode 100644 index 0000000..7281ed9 --- /dev/null +++ b/man/INSTALL @@ -0,0 +1,12 @@ +Imstallation of fehQlibs man pages +================================== + +a) It is expected that the fehQlibs are installed at /usr/local. +b) Check your manpath settings: $ manpath +c) You might want to compress the manpages: gzip *.3 +d) If available, the compressed or raw man pages can be simply copied to + - /usr/local/man/man3 or + - /usr/local/share/man/man3 + 'root' is required to complete this step. + +That's it! diff --git a/man/alloc.3 b/man/alloc.3 new file mode 100644 index 0000000..5bd40d2 --- /dev/null +++ b/man/alloc.3 @@ -0,0 +1,68 @@ +.TH qlibs: alloc 3 +.SH NAME +alloc \- allocate memory +.SH SYNTAX +.B #include \(dqalloc.h\(dq + +char *\fBalloc\fP(\fInew\fR); + +void \fBalloc_free\fP(\fIx\fR); + +void \fBalloc_re\fP(&\fIx\fR,\fIold\fR,\fInew\fR); + +char *\fIx\fR; +.br +unsigned int \fIold\fR; +.br +unsigned int \fInew\fR; +.SH DESCRIPTION +.B alloc +allocates enough space from the heap for +.I new +bytes of data, +adequately aligned for any data type. +.I new +may be 0. +.B alloc +returns a pointer to the space. +If space is not available, +.B alloc +returns 0, +setting +.B errno +appropriately. + +.B alloc_free +returns space to the heap. + +.B alloc_re +expands the space allocated to +.I x +from +.I old +bytes to +.I new +bytes. +It allocates new space, +copies +.I old +bytes from the old space to the new space, +returns the old space to the heap, +and changes +.I x +to point to the new space. +It then returns 1. +If space is not available, +.B alloc_re +returns 0, +leaving the old space alone. +.SH "CVE-2005-1513" +This version of +.B alloc +respects +.I limits.h +to avoid memory resource exhaustion. +.SH "SEE ALSO" +sbrk(2), +malloc(3), +error(3) diff --git a/man/buffer.3 b/man/buffer.3 new file mode 100644 index 0000000..2d4d0d2 --- /dev/null +++ b/man/buffer.3 @@ -0,0 +1,185 @@ +.TH buffer 3 +.SH NAME +buffer \- generic read/write buffering +.SH SYNTAX +.B #include \(dqbuffer.h\(dq + +buffer* buffer_0; /* like stdio's stdin */ +.br +buffer* buffer_1; /* like stdio's stdout */ +.br +buffer* buffer_2; /* like stdio's stderr */ + +void \fBbuffer_init\fR(buffer &\fIb\fR,ssize_t (*\fIop\fR)(int,char *,size_t), + int \fIfd\fR, char *\fIy\fR, size_t \fIylen\fR); +.br +ssize_t \fBbuffer_get\fP(buffer *\fIb\fR,char *\fIx\fR,size_t \fIlen\fR); + +int \fBbuffer_put\fP(buffer *\fIb\fR,const char *\fIx\fR,size_t \fIlen\fR); +.br +int \fBbuffer_puts\fP(buffer *\fIb\fR,const char *\fIx\fR); +.br +int \fBbuffer_putalign\fP(buffer *\fIb\fR,char *\fIx\fR,unsigned int \fIlen\fR); +.br +int \fBbuffer_putsalign\fP(buffer *\fIb\fR,char *\fIx\fR); + +int \fBbuffer_putflush\fP(buffer *\fIb\fR,char *\fIx\fR,unsigned int \fIlen\fR); +.br +int \fBbuffer_putsflush\fP(buffer *\fIb\fR,char *\fIx\fR); + +int \fBbuffer_flush\fP(buffer *\fIb\fR); +.br +int \fBbuffer_copy\fP(buffer *\fIbo\fR,buffer *\fIbi\fR); + +int \fBbuffer_unixread\fP(int \fIfd\fR,char *\fIbuf\fR,size_t \fIlen\fR); +.br +int \fBbuffer_unixwrite\fP(int \fIfd\fR,char *\fIbuf\fR,size_t \fIlen\fR); +.SH DESCRIPTION +.B buffer.h +describes a generic buffer interface that can be used for +read and write buffering. Buffers must be initialized with +\fBbuffer_init\fR. + +A buffer can only be used for reading or writing at the same time, not +both. + +Unlike +.BR stdio , +these write buffers are not flushed automatically at +program termination; you must manually call \fBbuffer_flush\fR, +\fBbuffer_putflush\fR, or \fBbuffer_putsflush\fR. + +.B buffer_init +prepares \fIb\fR to store a string in \fIy\fR[0], \fIy\fR[1], ..., +\fIy\fR[\fIylen\fR-1]. Initially the string is empty. + +.B buffer_init +also prepares \fIb\fR to use the read/write operation specified by +\fIop\fR and \fIfd\fR. + +You can use + + buffer \fIb\fR = BUFFER_INIT(\fIop\fR,\fIfd\fR,\fIy\fR,\fIylen\fR); + +to initialize \fIb\fR statically if \fIop\fR, \fIfd\fR, \fIy\fR, and \fIylen\fR +are compile-time constants. + +You can call +.B buffer_init +again at any time. Note that this discards the currently buffered string. + +.B buffer_get +copies data to \fIx\fR[0], \fIx\fR[1], ..., +\fIx\fR[\fIlen\fR-1] from the beginning of a string stored in +preallocated space; removes these \fIlen\fR bytes from the string; and +returns \fIlen\fR. + +If, however, the string has fewer than \fIlen\fR (but more than 0) +bytes, +.I buffer_get +copies only that many bytes, and returns that number. + +If the string is empty, +.B buffer_get +first uses a \fBread operation\fR to +feed data into the string. The \fBread operation\fR may indicate end of +input. + +The preallocated space and the \fBread operation\fR are specified by +\fIb\fR. You must initialize \fBb\fR using +.B buffer_init +before calling +.B buffer_get +(or use the pre-initialized \fIbuffer_0\fR). + +.B buffer_put +writes \fIlen\fR bytes from \fIx\fR to \fIb\fR. + +The difference to +.B buffer_putalign +is that, when there isn't enough space +for new data, +.B buffer_put +calls +.B buffer_flush +before copying any data, while +.B buffer_putalign +fills all available space with data before calling +.B buffer_flush. + +.B buffer_copy +copies one buffer to other one. +The output buffer needs to have at least the +preallocated size of the input buffer. +.B buffer_unixread +and +.B buffer_unixwrite +perform the same operation like standard Unix +.B read +or +.BR write. +.SH MACROS +Apart from this basic usage, some helpful macro +definitions are provided: +.B BUFFER_INIT(op,fd,buf,len) +uses +.I op +function to operate (read/write) on +.I buf +with +.I len +to file descriptor +.IR fd . +.B buffer_GETC(buf,c) +returns the upmost position of character +.I c +within buffer +.I buf +or 0. +.B buffer_PUTC(buf,c) +adds character +.I c +to buffer +.IR buf. +.SH EXAMPLE + #include <buffer.h> + #include <open.h> + + char buf[BUFFER_INSIZE]; // defined in buffer.h + int fd = open_read("/etc/services"); + buffer input; + + if (fd >= 0) { + char x; + buffer_init(&input,read,fd,buf,sizeof buf); + while (buffer_get(&input,&x,1) == 1) { + buffer_put(buffer_1,&x,1); + if (x == '\\n') break; + } + buffer_flush(buffer_1); + } +.SH "RETURN CODES" +.B buffer_put +and +.B buffer_get +return +.I 0 +if everything was fine, +.IR -1 , +on error (setting \fIerrno\fR). +.B buffer_copy +returns +.IR -2 , +if the input buffer can't be read, and +.IR -3 , +if the data can't successfully copied +to the output buffer. On success +.B buffer_copy +returns +.IR 0 . +.SH "REFERENCES" +https://cr.yp.to/lib/buffer_get.html + +https://cr.yp.to/lib/buffer_put.html +.SH "SEE ALSO" +stdio(3) diff --git a/man/byte.3 b/man/byte.3 new file mode 100644 index 0000000..277e479 --- /dev/null +++ b/man/byte.3 @@ -0,0 +1,82 @@ +.TH qlibs byte 3 +.SH NAME +byte \- byte manipulation/evaluation +.SH SYNTAX +.B #include \(dqbyte.h\(dq + +unsigned int \fBbyte_chr\fP(const char *\fIhaystack\fR,unsigned int \fIlen\fR,char \fIneedle\fR); +.br +unsigned int \fBbyte_rchr\fP(const char *\fIhaystack\fR,unsigned int \fIlen\fR,char \fIneedle\fR); + +void \fBbyte_copy\fP(char *\fIout\fR,unsigned int \fIlen\fR,const char *\fIin\fR); +.br +void \fBbyte_copyr\fP(char *\fIout\fR,unsigned int \fIlen\fR,const char *\fIin\fR); + +int \fBbyte_diff\fP(const char *\fIone\fR,unsigned int \fIlen\fR,const char *\fItwo\fR); + +int \fBbyte_equal\fP(const char *\fIone\fR,unsigned int \fIlen\fR,const char *\fItwo\fR); + +void \fBbyte_fill\fP(char *\fIout\fR,unsigned int \fIlen\fR,const char \fIc\fR); +.br +void \fBbyte_zero\fP(char *\fIout\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +.B byte_chr +returns the smallest integer \fIi\fR between 0 and +\fIlen\fR-1 inclusive such that \fIone\fR[\fIi\fR] equals \fIneedle\fR. +If no such integer exists, +.B byte_chr +returns \fIlen\fR. +.B byte_chr +may read all bytes \fIone\fR[0], \fIone\fR[1], ..., +\fIone\fR[\fIlen\fR-1], even if not all the bytes are relevant to the +answer. + +.B byte_rchr +returns the largest integer \fIi\fR between 0 and +\fIlen\fR-1 inclusive such that \fIone\fR[\fIi\fR] equals \fIneedle\fR. +If no such integer exists, +.B byte_rchr +returns \fIlen\fR. +.B byte_rchr +may read all bytes \fIone\fR[0], \fIone\fR[1], ..., +\fIone\fR[\fIlen\fR-1], even if not all the bytes are relevant to the +answer. + +.B byte_copy +copies \fIin\fR[0] to \fIout\fR[0], \fIin\fR[1] to +\fIout\fR[1], etc., and finally \fIin\fR[\fIlen\fR-1] to +\fIout\fR[\fIlen\fR-1]. + +.B byte_copyr +copies \fIin\fR[\fIlen\fR-1] to \fIout\fR[\fIlen\fR-1], +\fIin\fR[\fIlen\fR-2] to \fIout\fR[\fIlen\fR-2], etc., and +\fIin\fR[0] to \fIout\fR[0]. + +.B byte_diff +returns negative, 0, or positive, depending on whether +the string \fIone\fR[0], \fIone\fR[1], ..., \fIone\fR[\fIlen\fR-1] is +lexicographically smaller than, equal to, or greater than the string +\fIone\fR[0], \fIone\fR[1], ..., \fIone\fR[\fIlen\fR-1]. +When the strings are different, +.B byte_diff +does not read bytes past the first difference. + +.B byte_equal +returns +.I 1 +if the strings are equal, +.I 0 +otherwise. +When the strings are different, +.B byte_equal +does not read bytes past the first difference. + +.B byte_fill +fills \fIout\fR[0], \fIout\fR[1], ..., \fIout\fR[\fIlen\fR-1] +with a single byte \fIc\fR. + +.B byte_zero +sets \fIout\fR[0], \fIout\fR[1], ..., \fIout\fR[\fIlen\fR-1] to 0. +.SH "SEE ALSO" +case(3), +stralloc(3) diff --git a/man/case.3 b/man/case.3 new file mode 100644 index 0000000..c9a879a --- /dev/null +++ b/man/case.3 @@ -0,0 +1,124 @@ +.TH qlibs: case 3 +.SH NAME +case \- case independent string manipulation/evaluation +.SH SYNTAX +.B #include \(dqcase.h\(dq + +void \fBcase_lowers\fP(\fIs\fR); +.br +void \fBcase_lowerb\fP(\fIs\fR,\fIlen\fR); +.br +void \fBcase_uppers\fP(\fIs\fR); +.br +void \fBcase_upperb\fP(\fIs\fR,\fIlen\fR); +.br +int \fBcase_diffs\fP(\fIs\fR,\fIt\fR); +.br +int \fBcase_equals\fP(\fIs\fR,\fIt\fR); +.br +int \fBcase_diffrs\fP(\fIs\fR,\fIt\fR); +.br +int \fBcase_equalrs\fP(\fIs\fR,\fIt\fR); +.br +int \fBcase_starts\fP(\fIs\fR,\fIt\fR); +.br +int \fBcase_diffb\fP(\fIs\fR,\fIlen\fR,\fIt\fR); +.br +int \fBcase_startb\fP(\fIs\fR,\fIlen\fR,\fIt\fR); + +char *\fIs\fR; +.br +char *\fIt\fR; +.br +unsigned int \fIlen\fR; +.SH DESCRIPTION +.B case_lowers +converts each uppercase byte in the string +.I s +to lowercase. +.I s +must be 0-terminated. + +.B case_lowerb +converts each uppercase byte in the buffer +.IR s , +of length +.IR len , +to lowercase. + +.B case_uppers +converts each lowercase byte in the string +.I s +to uppercase. +.I s +must be 0-terminated. + +.B case_upperb +converts each lowercase byte in the buffer +.IR s , +of length +.IR len , +to uppercase. + +.B case_diffs +lexicographically compares lowercase versions of the strings +.I s +and +.IR t . +It returns something positive, negative, or zero +when the first is larger than, smaller than, or equal to the second. +.I s +and +.I t +must be 0-terminated. + +.B case_equals +means +.BR !case_diffs . + +.B case_diffrs +and +.B case_equalrs +compare strings from right to left instead from left to right. + +.B case_starts +returns 1 if a lowercase version of +.I s +starts with a lowercase version of +.IR t . +.I s +and +.I t +must be 0-terminated. + +.B case_diffb +lexicographically compares lowercase versions of the buffers +.I s +and +.IR t , +each of length +.IR len . +It returns something positive, negative, or zero +when the first is larger than, smaller than, or equal to the second. + +.B case_startb +returns 1 if a lowercase version of the buffer +.IR s , +of length +.IR len , +starts with a lowercase version of the string +.IR t . +.I t +must be 0-terminated. + +The +.B case +routines +are ASCII-specific. +They are suitable for programs that handle +case-independent networking protocols. + +All comparisons are performed on unsigned bytes. +.SH "SEE ALSO" +byte(3), +stralloc(3) diff --git a/man/cdbmake.3 b/man/cdbmake.3 new file mode 100644 index 0000000..7e7fd3e --- /dev/null +++ b/man/cdbmake.3 @@ -0,0 +1,61 @@ +.TH qlibs:cdbmake 3 +.SH NAME +cdmake \- generate and fill a constant database +.SH SYNTAX +.B #include \(dqcdmake.h\(dq + +int \fBcdb_make_start\fP(struct cdb *\fIc\fR,int \fIfd\fR); +.br +int \fBcdb_make_add\fP(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned int \fIkeylen\fR, + char *\fIdata\fR,unsigend int \fIdatalen\fR); +.br +int \fBcdb_make_finish\fP(struct cdb *\fIc\fR); +.SH DESCRIPTION +.B cdb_make_start +generates and intitialises a new cdb named +.I c +and makes it available via file descriptor +.IR fd . + +.B cdb_make_add +adds entries using the file descriptor +.I fd +given as +.I key +with length +.I keylen +into the cdb returning the hashed values +.I data +with length +.IR datalen . + +.B cdb_make_finish +finalises the data structure provided as +.IR fd . + +.SH "RETURN CODES" +Usually, the +.B cdb_make_* +routines provide a return code of +.I 0 +for successful operations and +.I -1 +if anything is going wrong. + +.SH EXAMPLE +#include <cdbmake.h> + + int fd; + stralloc data = {0}; + stralloc key = {0}; + + struct cdb_make c; + + if (cdb_make_start(&c,fd) == -1) die_write(); + if (cdb_make_add(&c,key.s,key.len,data.s,data.len) == -1) + die_write(); + if (cdb_make_finish(&c) == -1) die_write(); + if (fsync(fd) == -1) die_write(); + +.SH "SEE ALSO" +cdbread(3) diff --git a/man/cdbread.3 b/man/cdbread.3 new file mode 100644 index 0000000..6d4641f --- /dev/null +++ b/man/cdbread.3 @@ -0,0 +1,177 @@ +.TH qlibs:cdbread 3 +.SH NAME +cdbread \- fetch information from a constant database +.SH SYNTAX +.B #include \(dqcdbread.h\(dq + +void \fBcdb_init\fP(struct cdb *\fIc\fR,int \fIfd\fR); +.br +int \fBcdb_read\fP(struct cdb *\fIc\fR,char *\fIdata\fR,unsigned int \fIdlen\fR,uint32 \fIpos\fR); +.br +int \fBcdb_findstart\fP(int \fIfd\fR,char *\fIkey\fR,unsigned int \fIlen\fR); +.br +int \fBcdb_findnext\fP(int \fIfd\fR,char *\fIkey\fR,unsigned int \fIlen\fR); +.br +int \fBcdb_find\fP(int \fIfd\fR,char *\fIney\fR,unsigned int \fIlen\fR); + +.br +int \fBcdb_findnext\fP(int \fIfd\fR,char *\fIkey\fR,unsigned int \fIlen\fR); +.br +void \fBcdb_free\fP(struct cdb *\fIc\fR): +.SH DESCRIPTION +.B cdb_free +unallocates +.I c +if +.I c +is allocated. +Otherwise it leaves +.I c +alone. +.B cdb_free +does not close +.IR fd . + +.B cdb_init +allocates +.B c +to hold information about a constant database read by descriptor +.IR fd . +You may call +.B cdb_init +repeatedly; if +.I c +is already allocated, +.B cdb_init +unallocates it first. + +.B cdb_read +reads +.I dlen +bytes into +.I d +from byte position +.I dpos +in the database. You must allocate +.I c +before calling +.BR cdb_read . +Normally +.B cdb_read +returns +.IR 0 . +If the database file is shorter than +.I dpos+dlen +bytes, or if there is a disk read error, +.B cdb_read +returns +.IR -1 , +setting +.I errno +appropriately. + +.B cdb_findstart +prepares +.I c +to search for the first record under a new +.IR key . +You must allocate +.I c +before calling +.BR cdb_findstart , +and you must call +.B cdb_findstart +before calling +.BR cdb_findnext . + +.B cdb_findnext +looks for the nth record under +.I key +in the database, where +.I n +is the number of calls to +.B cdb_findnext +after the most recent call to +.BR cdb_findstart . +If it finds the record, +.B cdb_findnext +returns +.IR 1 ; +if there are exactly n-1 such records, +.B cdb_findnext +returns +.IR 0 ; +if there are fewer than n-1 such records, the behavior of +.B cdb_findnext +is undefined; if there is a database format error or disk error, +.B cdb_findnext +returns +.IR -1 , setting +.I errno +appropriately. Each call to +.B cdb_findnext +(before another call to +.BR cdb_findstart ) +must use the same +.I k +and +.IR klen . + +If +.B cdb_findnext +returns +.IR 1 , +it arranges for +.B cdb_datapos +to return the starting byte position of the data in the record, and for +.B cdb_datalen +to return the number of bytes of data in the record. +Otherwise the results of +.B cdb_datapos +and +.B cdb_datalen +are undefined. + +.B cdb_find +is the same as +.B cdb_findstart +followed by +.BR cdb_findnext : +it finds the first record under +.IR key. + +.B cdb_datapos +and +.B cdb_datalen +are macros pointing to the found information following +.I key +in the cdb and returning their length. +.SH EXAMPLE +#include <cdbread.h> + + int fd; + char *data; + unsigned int len; + stralloc key = {0}; + + static struct cdb c; + + cdb_init(&c,fd); + + switch (cdb_find(&c,key.s,key.len)) { + case -1: return -1; + case 0: return 0; + } + + len = cdb_datalen(&c); + data = alloc(len); + if (!data) return -1; + + if (cdb_read(&c,data,datalen,cdb_datapos(&c)) == -1) { + alloc_free(data); + return -1; + } + + cdb_free(&c); +.SH "SEE ALSO" +cdbmake(3) diff --git a/man/constmap.3 b/man/constmap.3 new file mode 100644 index 0000000..e28f5f4 --- /dev/null +++ b/man/constmap.3 @@ -0,0 +1,56 @@ +.TH qlibs:constmap 3 +.SH NAME +constmap \- fetch matching strings from a hashed data structure in constant time +.SH SYNTAX +.B #include \(dqconstmap.h\(dq +.SH SYNOPSIS +int \fBconstmap_init\fP(struct constmap \fI*cm\fR,char \fI*string\fR,int \fIlen\fR,int \fIflagcolon\fR); +.br +int \fBconstmap_init_char\fP(struct constmap \fI*cm\fR,char \fI*string\fR,int \fIlen\fR,int \fIflagcolon\fR,char \fIflagchar\fR); +.br +char *\fBconstmap\fP(struct constmap \fI*cm\fR,char \fI*string\fR,int \fIlen\fR); +.br +void \fBconstmap_free\fP(\fIstruct constmap *cm\fR); +.SH DESCRIPTION +Reading a file perhaps with +.I control_readfile(&cmap,"path/filename",0) +.B constmap_init +can be used to convert its content into a constant time search map: +.IR constmap . +Here, you can specify whether the entries in +.I constmap +are plain or key/value structured setting +.I flagcolon +to one and assuming the delimiter equals to a colon: +.IR : . +If the delimiter needs to be particulary tailored, use +.BR constmap_init_char . + +Given the search +.I string +and providing its length +.I len +(without the trailing \\0) +.B constmap +will now retrieve the information in constant time +returning a pointer to the search result or +.IR 0 . + +The datastructure can be freed by means of +.BR constmap_free . +.SH EXAMPLE +#include <constmap.h> + + struct constmap cmap; + stralloc result = {0}; + char *info; + char *search; + + if (control_readfile(&cmap,"control/conf",0)) + constmap_init(&cmap,result.s,result.len,1)); + + info = constmap(&cmap,search,str_len (search)); + if (!info) return 0; + +.SH "SEE ALSO" +cdbread(3), cdbmake(3) diff --git a/man/dns.3 b/man/dns.3 new file mode 100644 index 0000000..837450c --- /dev/null +++ b/man/dns.3 @@ -0,0 +1,249 @@ +.TH qlibs: dnsresolv +.SH NAME +dns \- dns resolver routines +.SH SYNTAX +.B #include \(dqdnsresolv.h\(dq + +int \fBdns_ip4_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); +.br +int \fBdns_ip4\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR); + +int \fBdns_ip6_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); +.br +int \fBdns_ip6\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR); + +int \fBdns_mx\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR); +.br +int \fBdns_mx_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); + +void \fBdns_name4_domain\fP(char \fIq\fR[DNS_NAME4_DOMAIN],const char *\fIip\fR[4]); +.br +int \fBdns_name4\fP(stralloc *\fIout\fR,const char *\fIip\fR[4]); + +void \fBdns_name6_domain\fP(char \fIq\fR[DNS_NAME6_DOMAIN],const char *\fIip\fR[16]); +.br +int \fBdns_name6\fP(stralloc *\fIout\fR,const char *\fIip\fR[16]); + +int \fBdns_name\fP(stralloc *\fIout\fR,const char *\fIip\fR[16]); +.br +int \fBdns_name_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); + +int \fBdns_txt\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR); +.br +int \fBdns_txt_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); + +int \fBdns_cname\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR); +.br +int \fBdns_cname_packet\fP(stralloc *\fIout\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR); + +int \fBdns_ip4_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR); +.br +int \fBdns_ip6_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR); +.br +int \fBdns_ip_qualify\fP(stralloc *\fIout\fR,stralloc *\fIfqdn\fR,const stralloc *\fIudn\fR); +.SH DESCRIPTION +.B dns_ip[4|6]_packet +is a low-level component of +.BR dns_ip[4|6] , +designed to support asynchronous DNS lookups. +It reads a DNS packet of length \fIlen\fR from +\fIbuf\fR, extracts the IP(4|6) addresses from the answer section of the packet and +puts the addresses into \fIout\fR. + +.B dns_ip[4|6] +looks up 4/16-byte IPv6 addresses for the fully qualified domain name of +\fIfqdn\fR. It puts the concatenation of the IPv[4|6] addresses into \fIout\fR and +returns the number of received answers for \fIfqdn\fR or \fI0\fR if none are replied. +If the domain does not exist in DNS, or has no IP addresses, +\fIout\fR will be empty. More generally, if \fIfqdn\fR is considered by +.B dns_ip4 +to be a dotted-decimal IPv4 address, it is provissioned as \fIout\fR +without checking the DNS while returning \fI1\fR. +Brackets may enclose the dotted-decimal IP address; they are ignored. + +.B dns_name[4|6]_packet +is a low-level component of +.B dns_name[4|6] +designed to support asynchronous DNS lookups. +It reads a DNS packet of length \fIlen\fR from \fIbuf\fR, + +.B dns_name[4|6]_domain +is a low-level component of +.BR dns_name[4|6] . +It converts an IP address such as +.I 1.2.3.4 +or +.I 4321:0:1:2:3:4:567:89ab +into a domain name such as +.I 4.3.2.1.in-addr.arpa +or +.I b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa +and places the packet-encoded domain name into \fIq\fR. +.I q +is zero terminated. +.I q +must have space for DNS_NAME[4|6]_DOMAIN bytes. + +.B dns_mx_packet +is a low-level component of +.BR dns_mx , +designed to support asynchronous DNS lookups. +It reads a DNS packet of length \fIlen\fR from \fIbuf\fR, +extracts the MX records from the answer section of the packet, puts the +result into \fIout\fR, and returns the number of replies received +or \fI-1\fR the same way as +.BR dns_mx . + +.B dns_mx +looks up MX records for the fully-qualified domain name in +\fIfqdn\fR. It puts the MX records into \fIout\fR and returns the number of +received records or \fI0\fR. +Each MX record is a two-byte MX distance (big endian) followed by a +\\0-terminated dot-encoded domain name. If the domain does not exist in +DNS, or has no MX records, \fIout\fR will be empty. + +.B dns_txt_packet +is a low-level component of +.BR dns_txt , +designed to support +asynchronous DNS lookups. It reads a DNS packet of length \fIlen\fR from \fIbuf\fR, +extracts the TXT records from the answer section of the packet, puts the +result into \fIout\fR, and returns the number of replies +or \fI-1\fR the same way as \fBdns_txt\fR. + +.B dns_txt +looks up TXT records for the fully-qualified domain name in +\fIfqdn\fR. It puts the concatenation of the TXT records into \fIout\fR +and returns the number of replies received. +If the domain does not exist in DNS, or has no TXT records, \fIout\fR will be empty. + +.B dns_cname_packet +is a low-level component of +.BR dns_cname , +designed to support +asynchronous DNS lookups. It reads a DNS packet of length \fIlen\fR from \fIbuf\fR, +extracts the TXT records from the answer section of the packet, puts the +result into \fIout\fR, and returns the number of replies received or +\fI-1\fR the same way as \fBdns_cname\fR. + +.B dns_cname +looks up the canonical name for a given +.IR fqdn . + +.B dns_ip[4|6]_qualify +feeds the name \fIudn\fR through qualification and looks up their +4-byte/16-byte IP addresses. It puts the fully qualified domain name +into \fIfqdn\fR and the concatenation of the IP addresses into \fIout\fR, +while returning the number of encountered IP addresses. +.B dns_ip[4|6]_qualify +evaluates the environment variables +.I $DNSREWRITEFILE +pointing to +.I /etc/dnsrewrite +and +.I $LOCALDOMAIN +and finally reading +.I /etc/resolv.conf +to build the +.I Full Qualified Domain Name (FQDN) +using the +.I domain suffix +for +.IR hostname . +.B dns_ip_qualify +returns +.I out +as +.I IP[4|6] +and +.IR FQDN . +If the domain does not exist in DNS, or has no IP addresses, +\fIout\fR will be empty and the return code is \fI0\fR. + +In case +.B dns_ip[4|6]_qualify +is fed with an +.I IP[4|6] +addresses instead of domain names, +it recognizes those not to be subject of +.IR qualification . +The particular names +.IR localhost , +.I ip4-loopback +and +.I ip6-loopback +are treated locally and mapped to +the respective +.I IP[4|6] +addresses (and vice versa) +without facilitating a DNS lookup. +.SH "INPUT" +For the high-level routines +.BR dns_ip[4|6] , +.BR dns_ip_qualify[4|6] , +.BR dns_name[4|6] , +.BR dns_mx , +.BR dns_name , +.BR dns_txt +and +.BR dns_cname +the provided input variable +.I stralloc \*\fqdn +needs to be un-terminated, thus the given +string length is identitical to the number of +.I fqdn +characters. +.SH "OUTPUT" +The returned IP addresses are given as character (byte) strings +with 4 or 16 bytes: +.B dns_ip4 +and +.B dns_ip4_qualifiy +return 4 byte IPv4 addresses, where as +.B dns_ip6 +and +.B dns_ip +as well as +.B dns_ip6_qualify +and +.B dns_ip_qualify +return sets of 16 byte IPv6 addresses, where +the potential IPv4 addresses are given in their +IPv6-mapped-IPv4 representation. +.SH "RETURN CODES" +The dns routines +.BR dns_cname* , +.BR dns_ip* , +.BR dns_mx* , +.B dns_name* +and +.BR dns_txt* +return the number of answers received, which may be +.I 0 +and potentially +.I -1 +in case of a memory failure. The full set of return codes: + +.EX +Value | Macro | Explaination +------+----------+------------------------------------- + n>0 | | n = number of answers reeceived + 0 | DNS_NXD | either NXDOMAIN or NODATA + -1 | DNS_MEM | out of memory (fatal) + -2 | DNS_ERR | parsing errors + -3 | DNS_COM | socket communicaton errror; SERVFAIL + -4 | DNS_INT | internal error + -5 | DNS_SOFT | DNS_ERR or DNS_COM + -6 | DNS_HARD | DNS loop problem (CNAME) +.EE + +.I errno +is set appropriately. +In case of a failure, the respective output variables like +\fIout\fR and \fIfqdn\fR may or may not change. +Since a received reply may be empty, always check the length of the +received output additionally. +.SH "SEE ALSO" +ip4(3), +ip6(3), +dnsstub(3) diff --git a/man/dnsstub.3 b/man/dnsstub.3 new file mode 100644 index 0000000..6bce8a3 --- /dev/null +++ b/man/dnsstub.3 @@ -0,0 +1,109 @@ +.TH qlibs: dnsstub +.SH NAME +dns \- stub resolver +.SH SYNTAX +.B #include \(dqdnsresolv.h\(dq + +int \fBdns_resolvconfip\fP(char \fIservers\fR[512],uint32 \fIscope\fR[32]); + +int \fBdns_transmit_start\fP(struct dns_transmit *\fIq\fR,const char \fIservers\fR[512], + int \fIflagrecursive\fR,const char *\fIq\fR,const char \fIqtype\fR[2], + const char \fIlocalip\fR[16]); +.br +int \fBdns_transmit_start6\fP(struct dns_transmit *\fIq\fR,const char \fIservers\fR[512], + int \fIflagrecursive\fR,const char *\fIq\fR,const char \fIqtype\fR[2], + const char \fIlocalip\fR[16],const uint32 \fIscopes\fR[32]); + +int \fBdns_sortip4\fP(char *\fIservers\fR,unsigned int \fIn\fR); +.br +int \fBdns_sortip6\fP(char *\fIservers\fR,unsigned int \fIn\fR); +.SH DESCRIPTION +.B dns_resolvconfip +reads the name servers defined in +.I /etc/resolv.conf +and uses +.B ip6_ifscan +to fetch their IPv4/IPv6 addresses together with the scope for the LLU address. +Up to +.I 32 +name servers can be specified. + +Apart from the system-wide +.I /etc/resolv.conf +the IP addresses of name servers can preferrably be provided by means of the +environment variable +.I $DNSCACHEIP +for each user application. The variable +.I $DNSCACHEIP +may include up to 32 name server IP addresses separated by white spaces: + +.EX + DNSCACHEIP="10.0.1.53 fe80::1%lo0 ::1" +.EE + +.B dns_transmit_start +and +.B dns_transmit_start6 +use the list of name server IP's for a recursive or none-recursive +query +.I q +of type +.I qtype +starting from IP address +.I localip +for which the +.I struct dns_transmit +provides the required book keeping information. +.B dns_transmit_start6 +additionally is able to evaluate the given +.I scope_id +as information for the local interface in order +to bind to the remote IPv6 LLU addresses. Usually +.I scope_id +defaults to +.IR 0 . + +.B dns_sortip4 +and +.B dns_sortip6 +randomize the list of name server IPs upon call and as result the first address +is used to facilitate the name lookup. +.IR FQDN . +.SH "RETURN CODES" +Different from the original djb implemtation, the +following return code scheme is used: +.TP 2 +rc > 0 +A 'positive' answer is given, thus results returned. +.TP 2 +rc = 0 +A 'neutral' answer was provided, thus typically the +operation succeeded, but without replies. +.TP 2 +rc < 0 +An operational error was encountered. +.TP 0 +Potentially, this needs to be treated specifically: +.TP 2 +DNS_INT (rc = -4) +Internal DNS operational error; ie. resources were not +available. +.TP 2 +DNS_COM (rc = -3) +DNS communication error. +.TP 2 +DNS_ERR (rc = -2) +Parsing errors and others. +.TP 2 +DNS_MEM (rc = -1) +Memory error occured. +.TP 0 +A 'safe' usage of return codes thus checks not only the presence +of a return code, but rather additionally its sign. +Negative return codes point to errors. +.SH "SEE ALSO" +http://cr.yp.to/djbdns/qualify.html, +dns(3), +ip4(3), +ip6(3), +socket_if(3) diff --git a/man/env.3 b/man/env.3 new file mode 100644 index 0000000..c8d0bf2 --- /dev/null +++ b/man/env.3 @@ -0,0 +1,68 @@ +.TH qlibs: env 3 +.SH NAME +env \- manage variables in the environment +.SH SYNTAX +.B #include \(dqenv.h\(dq + +char **\fBenviron\fP; + +char *\fBenv_put\fP(char *\fINAME\fR,char *\fIvalue\fR); +.br +char *\fBenv_puts\fP(char *\fINAME=value\fR); +.br +char *\fBenv_set\fP(char *\fINAME=value\fR); +.br +char *\fBenv_unset\fP(char *\fINAME\fR); +.br +char *\fBenv_get\fP(char *\fINAME\fR); +.br +char *\fBenv_pick\fP(); +.br +char *\fBenv_clear\fP(); +.SH DESCRIPTION +The environment, +.BR environ , +is a 0-terminated array of 0-terminated strings, +called environment variables. +Each environment variable is of the form +.IR NAME\fB=\fIvalue . + +.B env_puts +puts the string +.I \'NAME=value\' +into the environment. + +.B env_put +assigns the new enviromment variable +.I NAME +with +.IR value . + +.B env_set +assigns an existing environment variable +.I NAME +with +.IR value : +.IR \'NAME=value\' . + +.B env_unset +unsets an existing environment variable given as +.IR NAME . + +.B env_get +returns the assigned value of the first variable whose name is +.IR NAME , +or +.I 0 +if there is no such variable. + +.B env_pick +returns any variable in the environment, +or +.I 0 +if the environment is empty. + +.B env_clear +clears the whole envionment. +.SH "SEE ALSO" +environ(7) diff --git a/man/error.3 b/man/error.3 new file mode 100644 index 0000000..b96be1f --- /dev/null +++ b/man/error.3 @@ -0,0 +1,75 @@ +.TH qlibs: error 3 +.SH NAME +error \- syscall error codes and information +.SH SYNTAX +.B #include \(dqlogmsg.h\(dq + +extern int \fBerrno\fP; + +extern int \fBerror_intr\fP; +.br +extern int \fBerror_nomem\fP; +.br +extern int \fBerror_noent\fP; +.br +extern int \fBerror_txtbsy\fP; +.br +extern int \fBerror_io\fP; +.br +extern int \fBerror_exist\fP; +.br +extern int \fBerror_timeout\fP; +.br +extern int \fBerror_inprogress\fP; +.br +extern int \fBerror_wouldblock\fP; +.br +extern int \fBerror_again\fP; +.br +extern int \fBerror_pipe\fP; +.br +extern int \fBerror_perm\fP; +.br +extern int \fBerror_access\fP; + +char *\fBerror_str\fP(int \fIe\fR); + +int \fBerror_temp\fP(int \fIe\fR); +UNIX syscalls provide detailed error codes in the +.B errno +variable. +The +.B error +library provides portable names for a variety of possible +.B errno +values. + +.B error_str +returns a printable string describing syscall error code +.IR e . +Normally +.I e +is +.BR errno . + +.B error_temp +returns +.I 1 +if syscall error code +.I e +is a soft error, +.I 0 +if it is a hard error. Normally +.I e +is +.BR errno . + +A hard error is persistent: +file not found, read-only file system, symbolic link loop, etc. + +A soft error is usually transient: +out of memory, out of disk space, I/O error, disk quota exceeded, +connection refused, host unreachable, etc. +.SH "SEE ALSO" +sysmsg(3), +errno(2) diff --git a/man/fd.3 b/man/fd.3 new file mode 100644 index 0000000..b22338d --- /dev/null +++ b/man/fd.3 @@ -0,0 +1,79 @@ +.TH qlibs: fd 3 +.SH NAME +fd \- duplicate, move or close a file descriptor +.SH SYNTAX +.B #include \(dqfd.h\(dq + +int \fBfd_copy\fP(int \fIto\fR,int \fIfrom\fR); +.br +int \fBfd_move\fP(int \fIto\fR,int \fIfrom\fR); +.br +int \fBfd_coe\fP(int \fIfd\fR); +.SH DESCRIPTION +.B fd_copy +copies +descriptor +.I from +to descriptor +.IR to . +If +.I to +was already open, +.B fd_copy +closes it. +.B fd_copy +always leaves +.I from +intact; +if +.I to +and +.I from +are the same number, +.B fd_copy +does nothing. +.B fd_copy +does not guarantee that +.I to +will remain open, if it was open, in case of error. + +.B fd_move +moves +descriptor +.I from +to descriptor +.IR to . +If +.I to +was already open, +.B fd_move +closes it. +If the move is successful, +.B fd_move +closes +.IR from . +Exception: +if +.I to +and +.I from +are the same number, +.B fd_move +does nothing. + +.B fd_coe +closes +.IR fd . +.SH "RETURN CODES" +.BR fd_copy , +.BR fd_move , +and +.B fd_coe +return +.I 0 +on success, +and +.I -1 +on error. +.SH "SEE ALSO" +dup(2), fcntl(2) diff --git a/man/fmt.3 b/man/fmt.3 new file mode 100644 index 0000000..ac9c985 --- /dev/null +++ b/man/fmt.3 @@ -0,0 +1,90 @@ +.TH qlibs: fmt 3 +.SH NAME +fmt \- ASCII representation of strings and integers +.SH SYNTAX +.B #include \(dqfmt.h\(dq + +unsigned int \fBfmt_str\fP(char *\fIdest\fR,const char *\fIsource\fR); +.br +unsigned int \fBfmt_strn\fP(char *\fIdest\fR,const char *\fIsource\fR,unsigned int \fImaxlen\fR); + +unsigned int \fBfmt_uint\fP(char *\fIdest\fR,unsigned int \fIsource\fR); +.br +unsigned int \fBfmt_uint0\fP(char *\fIdest\fR,unsigned int \fIsource\fR,unsigned int \fIn\fR); +.br +unsigned int \fBfmt_ulong\fP(char *\fIdest\fR,unsigned long \fIsource\fR); +.br +unsigned int \fBfmt_xlong\fP(char *\fIdest\fR,unsigned long \fIsource\fR); +.br +char \fBtohex\fP(char \fInum\fR); +.br +int \fBfromhex\fP(unsigned char \fIc\fR); +.SH DESCRIPTION +.B fmt_str +copies all leading nonzero bytes from \fIsource\fR to \fIdest\fR +and returns the number of bytes it copied. +.B fmt_str +does not append \\0. + +.B fmt_strn +copies at most \fImaxlen\fR leading nonzero bytes from +\fIsource\fR to \fIdest\fR and returns the number of bytes it copied. +.B fmt_strn +does not append \\0. + +.B fmt_uint +writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. +.B fmt_uint +does not append \\0. + +.B fmt_uint0 +writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. +The output is padded with '0'-bytes until it encompasses at least +\fIn\fR bytes, but it will not be truncated if it does not fit. +.B fmt_uint0 +does not append \\0. + +.B fmt_ulong +writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written +perhaps including a trailing \\0. +.B fmt_ulong +does not append \\0. + +.B fmt_xlong +writes an ASCII representation ('0' to '9' and 'a' to 'f', base 16) +of \fIsource\fR to \fIdest\fR and returns the number of bytes +written. +.B fmt_xlong +does not append \\0. + +.B tohex +reads the ASCII representation of a decimal \fInum\fR and returns its +hexadecimal ASCII value; thus \'0\' -> \'0\' ... \'9\' -> \'9\', +\'10\' -> \'a\' and finally \'15\' -> f'. + +.B fromhex +reads the ACSII representation of a hexadecimal number \'0\' to \'f\' +irrelevant of its case and returns its integer value. + +For convenience, +.B fmt.h +defines the integers +.I FMT_LEN +and +.I FMT_ULONG +to be big enough to the number of bytes it would have written. + + +.SH "RETURN CODES" +If \fIdest\fR equals FMT_LEN (i.e. is zero), all +.B fmt_* +routins return the number of bytes it would have written +i.e. the number of leading nonzero bytes of \fIsource\fR +perhaps including a \\0. +.SH "SEE ALSO" +byte(3), +case(3), +scan(3) diff --git a/man/getln.3 b/man/getln.3 new file mode 100644 index 0000000..bb4ae7c --- /dev/null +++ b/man/getln.3 @@ -0,0 +1,102 @@ +.TH glibs: getln 3 +.SH NAME +getln \ - read one line of data +.SH SYNTAX +.B #include \(dqgetln.h\(dq + +int \fBgetln\fP(&buffer_0,&sa,&match,sep); +.br +int \fBgetln2\fP(&buffer_0,&sa,&cont,&clen,sep); + +buffer \fIbuffer_0\fR; +.br +stralloc \fIsa\fR; +.br +int \fImatch\fR; +.br +int \fIsep\fR; +.br +char *\fIcont\fR; +.br +unsigned int \fIclen\fR; +.SH DESCRIPTION +.B getln +reads a line of characters, terminated by a sep character, from +.IR buffer_0 . +It returns the line in +.I sa +and sets match to +.IR 1 . +If +.B getln +sees end-of-input before it sees +.IR sep , +it returns the partial line in +.I sa +and sets match to +.IR 0 . + +.B getln2 +reads a line of characters, terminated by a +.I sep +character, from +.IR buffer_0 . +The line is returned in two pieces. The first piece is stored in +.IR sa . +The second piece is +.IR cont , +a pointer to +.I clen +characters inside the +.I buffer_0 +buffer. The second piece must be copied somewhere else before +.I ss +is used again. +If +.B getln2 +sees end-of-input before it sees +.IR sep , +it sets +.I clen +to +.I 0 +and does not set +.IR cont . +It puts the partial line into +.IR sa. +.SH "RETURN CODES" +.B getln +normally returns +.IR 0 . +If it runs out of memory, or encounters an error from +.IR ss , +it returns +.IR -1 , +setting +.I errno +appropriately. + +.B getln2 +normally returns +.IR 0 . +If it runs out of memory, or encounters an error from +.IR ss , +it returns +.IR -1 , +setting +.I errno +appropriately. +.SH NOTE +The input buffer +.I buffer_0 +is already pre-allocated. +It can be used without initialization as synonym for STDIN. +.SH CREDITS +The +.B getln +and +.B getln2 +man page were taken from Bruce Guenther and +originally published by Dan Bernstein for qmail-1.03. +.SH SEE ALSO +stralloc(3) diff --git a/man/getoptb.3 b/man/getoptb.3 new file mode 100644 index 0000000..f3e329b --- /dev/null +++ b/man/getoptb.3 @@ -0,0 +1,22 @@ +.TH qlibs: getoptb 3 +.SH NAME +getoptb \- get option character from command line +.SH SYNTAX +.B #include \(dqgetoptb.h\(dq +.SH DESCRIPTION +Qlib's +.B getopt +is a replacement for the standard Unix +.B getopt +library, based on +.B sgetopt +and printing errors by means of +.B buffer +rather than +.BR stdio . + +See +.B getopt(3) +for interface details. +.SH "SEE ALSO" +buffer(3) diff --git a/man/iopause.3 b/man/iopause.3 new file mode 100644 index 0000000..c7ab9fb --- /dev/null +++ b/man/iopause.3 @@ -0,0 +1,87 @@ +.TH qlibs: iopause 3 +.SH NAME +iopause \- stateful handling of events based on the poll interface or file descriptors +.SH SYNTAX +.B #include \(dqioause.h\(dq + +int \fBiopause\fP(iopause_fd *\fIx\fR,unsigned int \fIlen\fR,struct taia *\fIdeadline\f$,struct taia *\fIstamp\fR); +.SH DESCRIPTION +.B iopause +checks for file descriptor readability or writeability as specified +by \fIx\fR[0].fd, \fIx\fR[0].events, \fIx\fR[1].fd, \fIx\fR[1].events, ..., \fIx\fR[\fIlen\fR-1].fd, +\fIx\fR[\fIlen\fR-1].events. If \fIx\fR[i].events includes the bit IOPAUSE_READ, +.B iopause +checks for readability of the descriptor \fIx\fR[i].fd; +if \fIx\fR[i].events includes the bit IOPAUSE_WRITE, +.B iopause +checks for writability of the descriptor +\fIx\fR[i].fd; other bits in \fIx\fR[i].events have undefined effects. + +.B iopause +sets the IOPAUSE_READ bit in \fIx\fR[i].revents if it finds that \fIx\fR[i].fd +is readabled and it sets the IOPAUSE_WRITE bit in \fIx\fR[i].revents if it finds +that \fIx\fR[i].fd is writable. +Beware that readability and writeability may be destroyed at any moment +by other processes with access to the same file \fIx\fR[i].fd refers to. + +If there is no readability or writeability to report, +.B iopause +waits until \fIdeadline\fR for something to happen. +.B iopause +will return before \fIdeadline\fR if a +descriptor becomes readable or writeable, or an interrupting signal +arrives, or some system-defined amount of time passes. +.B iopause +sets +.I revents +in any case. + +You must put a current timestamp into \fIstamp\fR before calling +.BR iopause . +In case the the current timestamp is older than the previous one (ie. due to daylight-saving) +negative values are omitted. + +.SH "IMPLEMENTATION NOTES" +The current implementation of +.B iopause +uses the \fBpoll\fR interface if that is available. +On some systems, \fBpoll\fR needs to dynamically allocate kernel +memory. In case not enough memory is available, +.B iopause +will return immediately and will report (often incorrectly) that no descriptors are +readable or writeable. + +If the \fBpoll\fR interface is not available, +.B iopause +uses the \fBselect\fR function. This function +cannot see descriptor numbers past a system-defined limit, typically 256 +or 1024; +.I iopause +will artificially pretend that those descriptors are never readable or writeable. + +Future implementations of +.B iopause +may work around these problems on some +systems, at the expense of chewing up all available CPU time. + +Both \fBpoll\fR and \fBselect\fR use relative timeouts rather than absolute deadlines. +Some kernels round the timeout down to a multiple of 10 milliseconds; this +can burn quite a bit of CPU time as the deadline approaches. +.B iopause +compensates for this by adding 20 milliseconds to the timeout. +In case the current timestamp is older than the previous one (ie. due to daylight-saving) +the timeout is set to 20 milliseconds. +.SH "RETURN CODES" +.B iopause +reads and deploys the return codes of the +.I poll +and +.I select +call. Only positive return values shall be considered by the calling routines for a succcessful +invocation. +.SH CREDITS +Parts of the description are taken from the 'libowfat' man page. +.SH "SEE ALSO" +select(2), +poll(3), +taia(3) diff --git a/man/ip4.3 b/man/ip4.3 new file mode 100644 index 0000000..d6b5928 --- /dev/null +++ b/man/ip4.3 @@ -0,0 +1,73 @@ +.TH qlibs: ipv4 +.SH NAME +ipv4 \- IPv4 address evaluation and conversion +.SH SYNTAX +.B #include \(dqip.h\(dq + +unsigned int \fBip4_fmt\fP(char *\fIs\fR,char \fIip[4]\fR); +.br +unsigned int \fBip4_scan\fP(const char *\fIs\fR,char \fIip[4]\fR); +.br +unsigned int \fBip4_scanbracket\fP(char *\fIs\fR,char \fIip[4]\fR); +.br +unsigned int \fBip_scanbracket\fP(char *\fIip_str\fR,char *\fIs\fR); +.br +unsigned int \fBip4_cidr\fP(char *\fIs\fR,char \fIip[4]\fR,unsigned long *\fIplen\fR); +.br +unsigned int \fBip4_bytestring\fP(stralloc *\fIip4string\fR,char \fIip[4]\fR,int \fIplen\fR); +.SH DESCRIPTION +.B ip4_fmt +reads the +.I char[4] +IPv4 address and returns a dotted-decimal IPv4 address string +.IR 1.2.3.4 . + +.B ip4_scan +reads an IPv4 address string +.I 1.2.3.4 +and converts it to the +.I char[4] +IPv4 address. + +.B ip4_scanbracket +reads an IPv4 address string enclosed in brackets +.I [1.2.3.4] +removes the brackets and calls +.B ip4_scan +on the result. + +.B ip_scanbracket +reads an IP address string enclosed in brackets +.I [1.2.3.4] +or +.IR [fe80::1] , +removes the brackets and calls +.B ip4_scan +or +.B ip6_scan +upon detecting an IPv6 address on the result. + +.B ip4_cidr +reads the CIDR IPv4 address string +.I 1.2.3.4/15 +determines the prefix as integer +.I plen +and calls +.BR ip4_scan . +If no prefix is identified, it returns 32. + +.B ip4_bytestring +reads the IPv4 address given as +.I char[4] +while returning a 0-terminated 'bytestring' representation +.I 1001001.... +up to the given prefix length +.IR plen . +.SH "RETURN CODES" +The +.B ip(4)* +programs return the number of bytes processed. +.B ip4_bytestring +returns regative numbers on failure. +.SH "SEE ALSO" +ip6(3), socket_if(3) diff --git a/man/ip6.3 b/man/ip6.3 new file mode 100644 index 0000000..f3f5cb1 --- /dev/null +++ b/man/ip6.3 @@ -0,0 +1,98 @@ +.TH qlibs: ipv6 +.SH NAME +ipv6 \- IPv6 address evaluation and conversion +.SH SYNOPSIS +.B #include \(dqip.h\(dq + +unsigned int \fBip6_fmt\fP(char *\fIs\fR,char \fIip[16]\fR); +.br +unsigned int \fBip6_fmt_flat\fP(char *\fIs\fR,char \fIip[16]\fR); +.br +unsigned int \fBip6_scan_flat\fP(const char *\fIs\fR,char \fIip[16]\fR); +.br +unsigned int \fBip6_scan\fP(const char *\fIs\fR,char \fIip[16]\fR); +.br +unsigned int \fBip6_scanbracket\fP(const char *\fIs\fR,char \fIip[16]\fR); +.br +unsigned int \fBip6_ifscan\fP(char *\fIs\fR,char \fIip[16]\fR,stralloc *\fIifname\fR); +.br +unsigned int \fBip6_cidr\fP(char *\fIs\fR,char \fIip[16]\fR,unsigned long *\fIplen\fR); +.br +unsigned int \fBip6_bytestring\fP(stralloc *\fIip6string\fR,char \fIip[16]\fR,int \fIplen\fR); +.SH DESCRIPTION +.B ip6_fmt +reads the +.I char[16] +IPv6 address and returns a compactified hexadecimal IPv6 address string +.IR fe80::fefe . + +.B ip6_fmt_flat +reads the +.I char[16] +IPv6 address and returns all hexadecimal IPv6 address labels as string +.IR fe80:0000:....:fefe . + +.B ip6_scan +reads a compactified IPv6 address string +.I fe80::fefe +and converts it to the +.I char[16] +IPv6 address. + +.B ip6_scan_flat +reads an uncompressed IPv6 address als hexadecimal string +and returns it's +.I char[16] +IPv6 address. + +.B ip6_scanbracket +reads a compactified IPv6 address string enclosed in brackets +.I [fe80::fefe] +removes the brackets and calls +.B ip6_scan +on the result. + +.B ip6_ifscan +reads the compactified IPv6 address string appended with the +interface_name +.I fe80::fefe%eth0 +returns +.I ifname +and calls +.B ip6_scan +for the (stripped) IPv6 address. + +.B ip6_cidr +reads the compactified CIDR IPv6 address string +.I fe80::fefe/64 +determines the prefix as integer +.I plen +and calls +.BR ip6_scan . +If no prefix is identfied, it returns 128. + +.B ip6_bytestring +reads the IPv6 address given as +.I char[16] +while returning a 0-terminated 'bytestring' representation +.I 1001001.... +up to the given prefix length +.IR plen . + +The macro +.B ipv6_v4mapped +reads the IPv6 addresses given as +.I char[16] +and returns +.I 0 +in case the given IPv6 address is not +a IPv4 mapped address. +.SH "RETURN CODES" +The +.B ip(6)* +programs return the number of bytes processed. +.B ip6_bytestring +returns negative numbers on failure. +.SH "SEE ALSO" +ip4(3), +socket_if(3) diff --git a/man/logmsg.3 b/man/logmsg.3 new file mode 100644 index 0000000..f819a18 --- /dev/null +++ b/man/logmsg.3 @@ -0,0 +1,109 @@ +.TH qlibs: logmsg 3 +.SH NAME +logmsg \- handle system errors and application log messages +.SH SYNTAX +.B #include \(dqlogmsg.h\(dq + +int logmsg(const char *who, int ecode, unsigned int classs, char *msg) + +\fBerr_sys\fR(w,e) logmsg(w,e,FATAL,"") +.br +\fBerr_sys_plus\fR(w,e,m) logmsg(w,e,FATAL,m) +.br +\fBerr_tmp\fR(w,e) logmsg(w,e,WARN,"") +.br +\fBerr_tmp_plus\fR(w,e,m) logmsg(w,e,WARN,m) +.br +\fBerr_int\fR(w,e,c) logmsg(w,e,c,"") +.br +\fBerr_int_plus\fR(w,e,c,m) logmsg(w,e,c,m) +.br +\fBlog_who\fR(w,m) logmsg(w,0,LOG,m) +.br +\fBlog_anon\fR(m) logmsg("",0,LOG,m) +.SH DESCRIPTION +\fBlogmsg\fR prints error, warning, or info/logging messages to stderr +and potentially terminates the calling program, depending on the \fIclass\fR given. +\fIwho\fR is the name of the program, \fIecode\fR is an error code, +\fIclass\fR determines the behavior upon call and \fImsg\fR is the logging message. +Read "error.h" to learn more about related constants. +.SH ECODE +\fIecode\fR is the error code and subject to be displayed in the log file and +potentially used upon exit if the \fIclass\fR equals \fBERROR\fR, \fBFATAL\fR, or \fBDROP\fR. + +To avoid conflicts with syscall error codes, appplication defined error codes should be negative. +The values \fI-15\fR, \fI-100\fR and \fI-111\fR are reserved for backward compatibility. +.SH CLASS +The \fIclass\fr parameter indicates how the application handles exceptions and displays the +log message. +.TP 4 +o +\fBLOG\fR, \fBINFO\fR, \fBALERT\fR, \fBWARN\fR - display message and continue operation +.TP 4 +o +\fBDROP\fR - display warning message and continue while returning to the calling program +.TP 4 +o +\fBUSAGE\fR, \fBSYNTAX\fR, \fBFATAL\fR, \fBERROR\fR +- display error message and exit application with error code +.RE + +\fBINFO\fR, \fBALERT\fR, \fBWARN\fR, \fBDROP\fR, \fBUSAGE\fR, and \fBFATAL\fR as well +as \fBERROR\fR display the respective class string like \fIwarning:\fR in the log message, +while \fBLOG\fR shows the log message only. + +The class \fBFATAL\fR should be used for system error codes only, rather \fBERROR\fR +and \fBWARN\fR shall be set in conjunction with an application error/warning. +.SH MESSAGE +If the custom message \fImsg\fR is given, it will be printed additionally. +.SH FORMAT +The log message format consists of the tokens +\fIwho\fR: (\fIecode\fR) \fImsg\fR : \fImsg\fR. +.I ecode +is displayed only for classes \fBFATAL\fR, \fBERROR\fR, or \fBDROP\fR. +.I msg +is the system's explanation according to the variable +.I errno +if provided. +.SH NOTES +.I logmsg.c +uses +.I errstr.c +routines. +Error codes and classes are defined in +.I error.h +and included by +.IR logmsg.h . +.SH "EXIT CODE" +\fBlogmsg\fR exits \fIecode\fR for classes \fBERROR\fR, \fBFATAL\fR, \fBSYNTAX\fR, +and \fBUSAGE\fR terminating the application. +.SH HISTORY +Dan Bernstein used sets of \fIstrerr_dieY*()\fR and \fIstrerr_warnY()\fR messages +which explicitely determine the message and behavior class. +Other classes were occasionally defined on demand, such als \fIusage()\fR. + +Kai Peter introduced the \fIerrmsg\fR facility in his \fBqlibs\fR +including a \fBsyslog\fR compliant \fIseverity\fR as second parameter. +.SH EXAMPLES +The macro definitions uses \fBw\fR for the calling program, +\fBe\fR for error code, \fBc\fR for class, and \fBm\fR for message. + + #include "logmsg.h" + #define WHO "my_prog" + + err_sys(WHO,errno); + err_sys_plus(WHO,-111,"additional message"); + + err_tmp("",-100); + err_tmp_plus("",errno,"additional message"); + + log_who(WHO,"message"); + +log_anon() is like log_who() but doesn't print the caller name. + +An user defined message \fBs\fR can be build from multiple arguments by using the \fIB\fR +(build) macro: + + err_sys_plus((errno),B("unable to run: ",*argv)); +.SH "SEE ALSO" +syslog(3) diff --git a/man/pathexec.3 b/man/pathexec.3 new file mode 100644 index 0000000..41dc978 --- /dev/null +++ b/man/pathexec.3 @@ -0,0 +1,124 @@ +.TH qlibs: pathexec 3 +.SH NAME +pathexec \- run a program within a given environment +.SH SYNTAX +.B #include \(dqpathexec.h\(dq + +\fBpathexec_run\fP(const char *\fIp\fR,char **\fIa\fR,char **\fIe\fR); +.br +\fBpathexec\fP(char *const *\fIa\fR); +.br +\fBpathexec_env\fP(const char *\fIs\fR,char *\fIt\fR); +.SH DESCRIPTION +.B pathexec_run +searches for a program named +.IR p . +It replaces the current process with a copy of that program. +The main function in that program will be given arguments +.I a +and environment +.IR e . +.B pathexec_run +looks for +.I p +as specified by the +.I $PATH +environment variable. +.I $PATH +is a colon-separated list of directories +.IR d ; +.B pathexec_run +tries +.B execve +on files named +.IR d/p , +in the order that the directories appear inside +.IR $PATH . +An empty directory name is treated as a single dot. + +If +.I $PATH +is not set, +.B pathexec_run +uses the path +.IR /bin:/usr/bin ; +i.e., it tries +.B execve +on +.IR /bin/p , +then +.IR /usr/bin/p . + +If +.I p +contains a slash, +.B pathexec_run +ignores +.I $PATH +and simply runs +.B execve +on a file named +.IR p . + +.B pathexec +calls +.B pathexec_run +with program name +.IR a[0] , +arguments +.IR a , +and the same environment as the current process, +modified as described below. +.B pathexec +has the same return behavior as +.BR pathexec_run . +.B pathexec_env +modifies the environment used by +.BR pathexec . +It removes a variable named +.IR s, +if one exists. It then adds a variable named +.I s +with value +.IR t, +if the pointer +.I t +is nonzero. The name +.I s +must not contain +.IR = . +.SH "RETURN CODES" +Normally +.B pathexec_run +does not return, because the process has been replaced. +However, if all the +.B execve +attempts fail, +.B pathexec_run +returns, setting +.I errno +to the most interesting error returned by +.BR execve . +Furthermore, +.B pathexec_run +returns immediately if an +.B execve +attempt fails with an error other than +.IR error_noent , +.IR error_acces , +.IR error_perm , +or +.IR error_isdir . +This list is subject to change. + +Normally +.B pathexec_env +returns +.IR 1 . +If it is unable to allocate memory, it returns +.IR 0 , +leaving the +.B pathexec +environment alone. +.SH "SEE ALSO" +error(3) diff --git a/man/scan.3 b/man/scan.3 new file mode 100644 index 0000000..a466daa --- /dev/null +++ b/man/scan.3 @@ -0,0 +1,81 @@ +.TH qlibs: scan 3 +.SH NAME +scan \- string to integer conversion +.SH SYNTAX +.B #include \(dqscan.h\(dq + +unsigned int \fBscan_8long\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.br +unsigned int \fBscan_uint\fP(const char *\fIsrc\fR,int *\fIdest\fR); +.br +unsigned int \fBscan_long\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.br +unsigned int \fBscan_ulong\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.br +unsigned int \fBscan_xint\fP(const char *\fIsrc\fR,int *\fIdest\fR); +.br +unsigned int \fBscan_xlong\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.SH DESCRIPTION +.B scan_8long +parses an unsigned long integer in octal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. + +.B scan_uint +parses an unsigned integer in decimal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. + +.B scan_ulong +parses an unsigned long integer in decimal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. +Leading + or - or space (or anything outside of 0-9) is not accepted. +The libc conventions of "023" for octal or "0x23" for hexadecimal are +not supported. +.B scan_ulong +will abort the scan if the next character is not a digit, or +if it is a digit but adding it to the number would lead to an integer +overflow. +.B scan_ulong +returns the number of characters successfully scanned and +processed from src. + +.B scan_long +includes the same logic as +.B scan_ulong +but now on a signed long integer in decimal ASCII format while +recognizing the leading '+' or '-' sign. + +.B scan_xint +parses an unsigned integer in hexadecimal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. + +.B scan_xlong +parses an unsigned long integer in hexadecimal ASCII +representation from \fIsrc\fR and writes the result into \fIdest\fR. It +returns the number of bytes read from \fIsrc\fR. +.B scan_xlong +understands both upper and lower case letters. +.B scan_xlong +does not expect or understand a "0x" prefix. +.SH EXAMPLES +scan_ulong("23",&i) -> i=23, return 2 + +scan_ulong("+23",&i) -> return 0 + +scan_ulong("-23",&i) -> return 0 + +scan_ulong(" 23",&i) -> return 0 + +scan_ulong("23,42",&i) -> i=23, return 2 + +scan_ulong("023",&i) -> i=23, return 3 + +scan_ulong("0x23",&i) -> i=0, return 1 + +scan_ulong("4294967296",&i) -> i=429496729, return 9 // 32-bit system +.SH "SEE ALSO" +case(3), +byte(3) diff --git a/man/socket_bind.3 b/man/socket_bind.3 new file mode 100644 index 0000000..434e45c --- /dev/null +++ b/man/socket_bind.3 @@ -0,0 +1,117 @@ +.TH qlibs: socket_bind 3 +.SH NAME +socket_bind \- binding a TCP/UDP socket to a local IP address, port, +and perhaps scope_id +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_bind4\fP(int \fIs\fR,char \fIip\fR[4],uint16 \fIport\fR); +.br +int \fBsocket_bind4_reuse\fP(int \fIs\fR,char \fIip\fR[4],uint16 \fIport\fR); + +int \fBsocket_bind6\fP(int \fIs\fR,char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); +.br +int \fBsocket_bind6_reuse\fP(int \fIs\fR,char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); + +int \fBsocket_bind\fP(int \fIs\fR,char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); +.br +int \fBsocket_bind_reuse\fP(int \fIs\fR,char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); +.SH DESCRIPTION +.B socket_bind4 +sets the local IP address and TCP/UDP port of a TCP/UDP +socket \fIs\fR to \fIip\fR and \fIport\fR respectively. + +.B socket_bind4_reuse +sets the local IP address and TCP/UDP port of a +TCP/UDP socket \fIs\fR to \fIip\fR and \fIport\fR respectively. +Unlike +.BR socket_bind4 , +this function will also tell the operating system +that the address is to be reused soon, which turns off the normal pause +before this IP and port can be bound again. + +.B socket_bind6 +sets the local IP address and TCP/UDP port of a TCP/UDP +socket \fIs\fR to \fIip\fR, \fIport\fR and \fIscope_id\fR respectively. + +.B socket_bind6_reuse +sets the local IP address and TCP/UDP port of a TCP/UDP socket \fIs\fR +to \fIip\fR, \fIport\fR and \fIscope_id\fR respectively. +Unlike +.BR socket_bind6 , +this function will also tell the operating system +that the address is to be reused soon, which turns off the normal pause +before this IP and port can be bound again. + +.B socket_bind +sets the local IPv4/IPv6 address and TCP/UDP port of a TCP/UDP +socket \fIs\fR to \fIip\fR, \fIport\fR, and \fIscope_id\fR respectively. + +For IPv4 and IPv4-mapped IPv6 addresses +.B socket_bind +will use +.B socket_bind4 +or otherwise +.BR socket_bind6 . + +.B socket_bind_reuse +sets the local IPv4/IPv6 address and TCP/UDP port of a TCP/UDP socket \fIs\fR +to \fIip\fR, \fIport\fR, and \fIscope_id\fR respectively. +Unlike +.BR socket_bind , +this function will also tell the operating system +that the address is to be reused soon, which turns off the normal pause +before this IP and port can be bound again. + +For IPv4 and IPv4-mapped IPv6 addresses +.B socket_bind_reuse +will use +.B socket_bind4_reuse +or otherwise +.BR socket_bind6_reuse . +.SH "AUTOMATIC BINDING" +If the IPv4 address is 0 or the IPv6 address is ::, the operating system +chooses a local IP address. +If \fIport\fR is 0, the operating system chooses a port. +\fIscope_id\fR is usually 0, except for IPv6 LLU addresses where +.B socket_getifidx +can be used to determine +.I scope_id +from the interface name. +.SH "RETURN CODES" +Normally, all +.I socket_bind* +routines return +.IR 0 . +If anything goes wrong, the return code is +.I -1 +and setting +.I errno +appropriately. +.SH EXAMPLE + #include <socket_if.h> + #include <ip.h> + + int \fIs\fR; + char \fIlcoalip\fR[16]; + char \fIremoteip\fR[16]; + uint16 \fIp\fR = 0; + uint32 \fIscope_id\fR = 0; + + if (ip6_isv4mapped(ip)) + s = socket_tcp4(); + else + s = socket_tcp6(); + if (s == -1) + err_tmp(111,"unable to create TCP socket: "); + + socket_connect(s,remoteip,p,scope_id); +.SH "SEE ALSO" +socket_if(3), +socket_connect(3), +socket_info(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_connect.3 b/man/socket_connect.3 new file mode 100644 index 0000000..e289393 --- /dev/null +++ b/man/socket_connect.3 @@ -0,0 +1,110 @@ +.TH qlibs: socket_connect 3 +.SH NAME +socket_connect \- initiate or test a socket connection to a remote IPv4/IPv6 address +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_connect4\fP(int \fIs\fR,const char \fIip\fR[4],uint16 \fIport\fR); +.br +int \fBsocket_connect6\fP(int \fIs\fR,const char \fIip\fR[16],uint16 \fIport\fR, + uint32 \fIscope_id\fR); +.br +int \fBsocket_connect\fP(int \fIs\fR,const char \fIip\fR[16],uint16 \fIport\fR, + uint32 \fIscope_id\fR); + +int \fBsocket_connected\fP(int \fIs\fR); +.SH DESCRIPTION +.B socket_connect4 +attempts to make a connection from TCP or UDP socket \fIs\fR to +TCP port \fIport\fR on IP address \fIip\fR. +You can call +.B socket_connect4 +without calling +.BR socket_bind4 . +This has the effect as first calling +.B socket_bind4 +with IP address 0.0.0.0 and port 0. + +.B socket_connect6 +attempts to make a connection from TCP or UDP socket \fIs\fR to +TCP port \fIport\fR on IP address \fIip\fR and \fIscope_id\fR. +The meaning of \fIscope_id\fR is dependent on the implementation and +IPv6 IP. For link-local IPv6 addresses it specifies the outgoing +interface index. From a given interface name (e.g. "eth0") +it's index can be retrieved with +.BR socket_getifidx . +\fIscope_id\fR should normally be set to 0. +You can call +.B socket_connect6 +without calling +.BR socket_bind6 . +This has the effect as first calling +.B socket_bind6 +with IP address :: and port 0. + +.B socket_connect +attempts to make a connection from TCP socket \fIs\fR to +TCP port \fIport\fR on IP address \fIip\fR and \fIscope_id\fR +calling +.BR socket_connect6 . +If however, \fIip\fR is an IPv4 or IPv4-mapped IPv6 address +.B socket_connect4 +is called instead. + +Once a socket is connected, you can use the read and write +system calls to transmit data. + +.B socket_connected +can be used to verify, whether a background connection failed or +succeeded, thus \fIs\fR became writable or not. +.SH EXAMPLE + #include <socket_if.h> + + int \fIs\fR; + char \fIlocalip\fR[16]; + char \fIremoteip\fR[16]; + uint16 \fIp\fR = 0; + + s = socket_tcp(); + socket_bind(s,localip,p,0); + socket_connect(s,remoteip,p,0); + + if (socket_connected(s) != 1) + err_tmp(""111,fatal,"unable to setup TCP connection: "); +.SH "RETURN CODES" +.BR socket_connect4 , +.BR socket_connect6 +and +.BR socket_connect +may return +.IR 0 , +to indicate that the connection succeeded (and succeeded immediately, +if the socket is non-blocking) +.IR -1 , +setting +.I errno +to error_inprogress or error_wouldblock, to indicate +that the socket is non-blocking +.IR -1 , +setting +.I errno +to something else, to indicate that the connection +failed (and failed immediately, if the socket is non-blocking). + +.B socket_connected +returns +.I 1 +if \fIs\fR is a socket and a connection is established, +.I 0 +otherwise and setting +.I errno +appropriately. +.SH "SEE ALSO" +socket_if(3), +socket_info(3), +socket_bind(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_if.3 b/man/socket_if.3 new file mode 100644 index 0000000..1c1ef70 --- /dev/null +++ b/man/socket_if.3 @@ -0,0 +1,97 @@ +.TH qlibs: socket_if 3 +.SH NAME +socket_if \- retrieve scope_id for interface name and vice versa +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +uint32 \fBsocket_getifidx\fP(const char *\fIifname\fR); + +const char *\fBsocket_getifname\fP(uint32 \fIscope_id\fR); +.SH DESCRIPTION +.B socket_getifidx +returns the \fIscope_id\fR of an interface named as +.I ifname +typically ''eth0''. + +.B socket_getifname +retrieves from the operating system's assigned +.I scope_id +the interface name +.IR ifname . +.SH INTERFACE_NAME VERSUS SCOPE_ID +For IPv6 LLU addresses an additional +.I ifname +(interface name) has to be provided accompanying the IPv6 address: +.IR fe80::1%eth0 . +The operating systems rather uses +.I scope_id +as index for +.IR ifname . + +For global IPv6 and ULA addresses +.I ifname +can be set to +.IR 0 . +Since IPv4 addresses on any interface are always unique, +simply use +.I 0 +for all cases. +.SH BACKGROUND +Qlib's socket routines provide an easy API to setup +TCP or UDP connections over IPv4 or IPv6 networks. Together with +Qlib's IP address parsing capabilities, a set of high-level +socket routines allow a common IPv4/IPv6 handling. +.SH SOCKET FILES +.TP 5 +.B socket_bind.c +bind to or reuse the local IPv4/IPv6 address and port +for a socket connection +.TP 5 +.B socket_connect.c +attempts to setup a TCP or UDP client connection +.TP 5 +.B socket_info.c +get local/remote IPv4/IPv6 address of socket +.TP 5 +.B socket_recv.c +set up a receiving IPv4/IPv6 connection +.TP 5 +.B socket_send.c +send UDP datagram over a IPv4 or IPv6 connection +.TP 5 +.B socket_setup.c +listen to and accept an IPv4/IPv6 TCP socket connection +.TP 5 +.B socket_tcp.c +create a non-blocking TCP stream socket +.TP 5 +.B socket_udp.c +create a non-blocking UDP datagram socket +.SH USAGE +Most of the above files include their IPv4 and +IPv6 counterparts together with a combined usage +requiring in addition a +.I scope_id +or simply +.IR 0 . +IPv4 addresses are usually converted upon reading to +IPv4-mapped IPv6 addresses using Qlib's IP address +parsing functions. +IPv4 and IPv6 socket calls - if required - +need to be distinguished +by the calling routines testing + +.EX + ip6_isv4mapped(ip) +.EE + +Otherwise, the unified IPv6/IPv4 versions will be used. +.SH "SEE ALSO" +socket_bind(3), +socket_connect(3), +socket_info(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_info.3 b/man/socket_info.3 new file mode 100644 index 0000000..899a7cb --- /dev/null +++ b/man/socket_info.3 @@ -0,0 +1,47 @@ +.TH socket_info 3 +.SH NAME +socket_info \- retrieving IP connection information for an existing socket +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_local\fP(int \fIs\fR,char \fIip\fR[16], + uint16 *\fIport\fR,uint32 *\fIscope_id\fR); + +int \fBsocket_remote\fP(int \fIs\fR,char \fIip\fR[16], + uint16 *\fIport\fR,uint32 *\fIscope_id\fR); +.SH DESCRIPTION +.B socket_local +returns the local IPv6 or IPv4-mapped IPv6 address as \fIip\fR, +port as \fIport\fR and perhaps the scope_id as \fIscope_id\fR for the UDP or TCP socket. + +.B socket_remote +returns the remote IPv6 or IPv4-mapped IPv6 address as \fIip\fR, +port as \fIport\fR and perhaps the scope_id as \fIscope_id\fR for the UDP or TCP socket. + +.SH "RETURN CODES" +If something goes wrong, +.B socket_local +and +.B socket_remote +return +.IR -1 , +setting +.I errno +appropriately. +.SH EXAMPLE +#include <socket_if.h> + int \fIs\fR; + char \fIip\fR[16]; + uint16 \fIport\fR; + + if (socket_remote(s,ip,&port,0) == -1) + err_tmp("",111,"unable to get remote address: "); +.SH "SEE ALSO" +socket_if(3), +socket_bind(3), +socket_connect(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_recv.3 b/man/socket_recv.3 new file mode 100644 index 0000000..bebef08 --- /dev/null +++ b/man/socket_recv.3 @@ -0,0 +1,56 @@ +.TH qlibs: socket_recv 3 +.SH NAME +socket_recv \- receive UDP datagrams over IPv4/IPv6 connections +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_recv\fP(int \fIs\fR, const char *\fIbuf\fR, unsigned int \fIlen\fR, + const char \fIip\fR[16], uint16 *\fIport\fR, uint32 *\fIscope_id\fR); +.SH DESCRIPTION +.B socket_recv +reads \fIlen\fR bytes starting at \fIbuf\fR in a UDP datagram +over the socket \fIs\fR while providing information about the +remote IP address \fIip\fR and the UDP \fIport\fR and +the perhaps \fIscope_id\fR of the receiving interface. + +You can call +.B socket_recv +without calling +.BR socket_bind . +This has the effect as first calling +.B socket_bind +with IP address :: and port 0. +.SH RETURN VALUE +.B socket_recv +returns +.IR 0 , +otherwise +.I -1 +and sets +.I errno +appropriately. +.SH EXAMPLE + #include <socket_if.h> + #include <ip.h> + + int \fIs\fR; + char \fIlocalip\fR[16]; + char \fIremoteip\fR[16]; + uint16 \fIp\fR, \fIport\fR; + uint32 \fIscope_id\fR; + unsigned int \fIlen\fR; + int \fIr\fR; + char buf[MTUSIZE+1]; + + s = socket_udp(); + socket_bind_reuse(s,localip,p,0); + r = socket_recv(s,buf,len,remoteip,&port,&scope_id); +.SH SEE ALSO +socket_if(3), +socket_info(3), +socket_bind(3), +socket_connect(3) +socket_send(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_send.3 b/man/socket_send.3 new file mode 100644 index 0000000..cf74300 --- /dev/null +++ b/man/socket_send.3 @@ -0,0 +1,76 @@ +.TH qlibs: socket_send 3 +.SH ROUTINES +socket_send \- sending data over a UDP socket +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_send4\fP(int \fIs\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR, + const char \fIip\fR[4],uint16 \fIport\fR); +.br +int \fBsocket_send6\fP(int \fIs\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR, + const char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); +.br +int \fBsocket_send\fP(int \fIs\fR,const char *\fIbuf\fR,unsigned int \fIlen\fR, + const char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR); +.SH DESCRIPTION +.B socket_send4 +sends \fIlen\fR bytes starting at \fIbuf\fR in a UDP +datagram over the socket \fIs\fR to UDP port \fIport\fR on IPv4 address +\fIip\fR. + +.B socket_send6 +sends \fIlen\fR bytes starting at \fIbuf\fR in a UDP datagram +over the socket \fIs\fR to UDP port \fIport\fR on IPv6 address \fIip\fR and perhaps +using \fIscope_id\fR as outging interface. + +For link-local IPv6 (LLU) addresses \fIscope_id\fR specifies the outgoing +interface index. +.I socket_id +can be queried for the given name of the interface (e.g. "eth0") by means of +.BR socket_getifidx . +\fIscope_id\fR should normally be set to 0 except for link local IPv6 addresses + +.B socket_send +sends \fIlen\fR bytes starting at \fIbuf\fR in a UDP datagram +over the socket \fIs\fR to UDP port \fIport\fR on IP address \fIip\fR and perhaps +using \fIscope_id\fR as outging interface. + +You can call +.B socket_send* +without calling +.BR socket_bind* . +This has the effect as first calling +.B socket_bind4 +with IP address 0.0.0.0 and port 0 +or +.B socket_bind6 +with IP address :: and port 0. +.SH RETURN VALUE +.B socket_send* +returns +.I 0 +if the datagram was sent successfully. If not, +it returns +.I -1 +and sets +.I errno +appropriately. +.SH EXAMPLE + #include <socket_if.h> + + int \fIs\fR; + char \fIip\fR[4]; + uint16 \fIp\fR; + + s = socket_udp(); + socket_bind(s,ip,p); + socket_send(s,"hello, world",12,ip,p,0); +.SH "SEE ALSO" +socket_if(3), +socket_info(3), +socket_bind(3), +socket_connect(3), +socket_recv(3), +socket_setup(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_setup.3 b/man/socket_setup.3 new file mode 100644 index 0000000..639b28b --- /dev/null +++ b/man/socket_setup.3 @@ -0,0 +1,105 @@ +.TH qlibs: socket_setup 3 +.SH NAME +socket_setup \- listen to or accept socket for incoming TCP connections +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_listen\fP(int \fIs\fR,int \fIn\fR); + +int \fBsocket_accept\fP(int \fIs\fR,char \fIip\fR[16], + uint16 *\fIport\fR,uint32 *\fIscope_id\fR); + +int \fBsocket_ipoptionskill\fR(int \fIs\fR); + +int \fBsocket_ip6anycast(\fR(int \fIs\fR); + +int \fBsocket_dualstack\fR(int \fIs\fR); + +int \fBsocket_nodualstack\fR(int \fIs\fR); +.SH DESCRIPTION +.B socket_listen +prepares TCP socket \fIs\fR to accept TCP connections. +It allows a backlog of approximately \fIn\fR TCP SYNs. +(On systems supporting SYN cookies, the backlog is irrelevant.) + +.B socket_accept +accepts the connection. It creates a new socket +for the connection and returns a file descriptor pointing to the new +socket; you can use the read and write system calls to transmit data +through that file descriptor. +Further, it provides information about client's +\fIip\fR address and TCP \fIport\fR number +perhaps together with local receiving interface \fIscope_id\fR. + +.B socket_ipoptionskill +is used to disable previously defined options in IPv4 or IPv6 packets +like Source Routing prior of using this socket for data exchange. +.B socket_ipoptionskill +uses the +.BR setsockopt . + +.B socket_ip6anycast +enables unspecified reversed anycasting on the listening socket +.IR s +with IPv6 address +.IR :: . +Upon receiving IPv6 packets, the socket records the +incoming IPv6 address and the receiving \fIscope_id\fR +in order provide additional routing information. + +.B socket_dualstack +and +.B socket_nodualstack +can be used to force or forbid dual-stack behavior +setting the +.B setsockopt +variable +.I IPV6_V6ONLY +appropriately. In the last case, a potential servers +needs two instances to accept incoming IPv6 and IPv6 packets. +.SH "RETURN CODES" +Normally +.BR socket_listen , +.B socket_accept +and +.B socket_ipotionskill +as well as +.B socket_dualstack +and +.B socket_nodualstack +return +.I 0 +and if anything goes wrong it returns +.IR -1 , +setting +.I errno +appropriately. +.SH EXAMPLE + #include <socket_if.h> + + int \fIs\fR, \fIt\fR; + int \fIr\fR; + char \fIip\fR[16]; + uint16 \fIp\fR; + + if ((s = socket_tcp()) == -1) + err_tmp("",111,"unable to create TCP socket: "); + r = socket_ipoptionskill(s); + if (socket_bind_reuse(s,(char *)V6localnet,8002,0) == -1) + err_tmp("",111,"unable to bind: "); + if (socket_listen(s,1) == -1) + err_tmp("",111,"unable to listen: "); + + t = socket_tcp(); + socket_bind(t,ip,p,0); + socket_listen(s,16); + socket_accept(t,ip,&p,&scope_id); +.SH "SEE ALSO" +socket_if(3), +socket_bind(3), +socket_connect(3), +socket_info(3), +socket_recv(3), +socket_send(3), +socket_tcp(3), +socket_udp(3) diff --git a/man/socket_tcp.3 b/man/socket_tcp.3 new file mode 100644 index 0000000..3616ed7 --- /dev/null +++ b/man/socket_tcp.3 @@ -0,0 +1,58 @@ +.TH qlibs: socket_tcp 3 +.SH NAME +socket_tcp \- setting up TCP sockets +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_tcp4\fP(); +.br +int \fBsocket_tcp6\fP(); +.br +int \fBsocket_tcp\fP(); +.SH DESCRIPTION +.B socket_tcp4 +creates a non-blocking TCP/IPv4 stream socket and +providing a file descriptor pointing to that socket. + +.B socket_tcp6 +creates a non-blocking TCP/IPv6 stream socket and +providing a file descriptor pointing to that socket. + +.B socket_tcp +creates a non-blocking IPv6 TCP/IP socket calling +.B socket_tcp6 +unless it can't bind to IPv6 and now facilitating +.BR socket_tcp4 . +.SH "REMOTE CODES" +All these routines return +.IR 0 +except in case of failures, returning +.I -1 +and setting +.I errno +appropriately, without allocating any resources. +.SH EXAMPLE + #include <socket_if.h> + + int \fIt\fR; + char \fIlocalip\fR[16]; + char \fIremoteip\fR[16]; + uint16 \fIp\fR; + + if (ip6_isv4mapped(remoteip)) { + t = socket_tcp4(); + socket_bind4(t,localip + 12,0); + } else { + t = socket_tcp6(); + socket_bind6(t,localip,0,0); + } + socket_connect(s,remoteip,p,0); +.SH "SEE ALSO" +socket_if(3), +socket_bind(3), +socket_connect(3), +socket_info(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_udp(3) diff --git a/man/socket_udp.3 b/man/socket_udp.3 new file mode 100644 index 0000000..eff0290 --- /dev/null +++ b/man/socket_udp.3 @@ -0,0 +1,58 @@ +.TH qlibs: socket_udp 3 +.SH NAME +socket_udp \- setting up UDP datagram sockets +.SH SYNTAX +.B #include \(dqsocket_if.h\(dq + +int \fBsocket_udp4\fP(); +.br +int \fBsocket_udp6\fP(); +.br +int \fBsocket_udp\fP(); +.SH DESCRIPTION +.B socket_udp4 +creates a non-blocking UDP/IPv4 datagram socket and +providing a file descriptor pointing to that socket. + +.B socket_udp6 +creates a non-blocking UDP/IPv6 datagram socket and +providing a file descriptor pointing to that socket. + +.B socket_udp +creates a non-blocking IPv6 UDP socket calling +.B socket_udp6 +unless it can't bind to IPv6 and now facilitating +.BR socket_tcp4 . + +.SH "REMOTE CODES" +All these routines return +.IR 0 +except in case of failures, returning +.I -1 +and setting +.I errno +appropriately, without allocating any resources. +.SH EXAMPLE + #include <socket_if.h> + int \fIu\fR; + char \fIlocalip\fR[16]; + char \fIremoteip\fR[16]; + uint16 \fIp\fR; // port + + if (ip6_isv4mapped(remoteip)) { + u = socket_udp4(); + socket_bind4(u,localip + 12,p); + } else + u = socket_udp6(); + socket_bind6(u,localip,p,0); + } + socket_connect(u,remoteip,p,0); +.SH "SEE ALSO" +socket_if(3), +socket_bind(3), +socket_connect(3), +socket_info(3), +socket_recv(3), +socket_send(3), +socket_setup(3), +socket_tcp(3) diff --git a/man/str.3 b/man/str.3 new file mode 100644 index 0000000..c8643ed --- /dev/null +++ b/man/str.3 @@ -0,0 +1,61 @@ +.TH qlibs: str 3 +.SH NAME +str \- string evaluation and comparision (for allocated strings) +.SH SYNTAX +.B #include \(dqstr.h\(dq + +unsigned int \fBstr_copy\fR(char *\fIdst\fR, const char *\fIsrc\fR); +.br +unsigned int \fBstr_copyb\fR(char *\fIdst\fR, const char *\fIsrc\fR, unsigned int \fIlen\fR); +.br +unsigned int \fBstr_chr\fR(const char *\fIs\fR, int \fIc\fR); +.br +unsigned int \fBstr_rchr\fR(const char *\fIs\fR, int \fIc\fR); +.br +unsigned int \fBstr_diff\fR(const char *\fIs\fR, const char *\fIt\fR); +.br +unsigned int \fBstr_diffn\fR(const char *\fIs\fR, const char *\fIt\fR, unsigned int \fIlen\fR); +.br +unsigned int \fBstr_equal\fR(const char *\fIs\fR, const char *\fIt\fR); +.br +unsigned int \fBstr_len\fP(const char *\fIs\fR); +.br +unsigned int \fBstr_starts\fP(const char *\fIdst\fR, const char *\fIsrc\fR); +.br +char *\fBstr_append\fP(char *\fIdst\fR, const char *\fIs\fR); +.SH DESCRIPTION +\fBstr_copy\fR copies \fIsrc\fR into \fIdst\fR up to the first occurance of \\0 while including it. +It returns the number of bytes written. +If \fIdst\fR is smaller than \fIsrc\fR, \fBstr_copy\fR fills up \fIdst\fR +to its allocated size and returns the number of bytes it would have be written. +\fBstr_copyb\fR copies \fIlen\fR bytes from \fIsrc\fR into \fIdst\fR. + +\fBstr_chr\fR and \fBstr_rchr\fR searches for a single character in a string +(from left-to-right or from right-to-left) and returns the position of +the \fIfirst\fR occurrance of \fIc\fR or the length \fIlen\fR of \fIs\fR. + +\fBstr_len\fR determines the length of a string. It returns the position +of the first occurance of \\0 in \fIs\fR. + +\fBstr_diff\fR, \fBstr_diffn\fR, and \fBstr_equal\fR compare two strings. +\fBstr_diff\fR and \fBstr_diffn\fR returns negative, zero or positive, depending +whether the string \fIs\fR[0], \fIs\fR[1], ..., \fIs\fR[n]=='\\0' is +ASCII lexicographically smaller than, equal to, or greater than the string +\fIt\fR[0], \fIt\fR[1], ..., \fIt\fR[m-1]=='\\0'. If the strings are different, +both functions do not read bytes past the first difference. +\fBstr_diffn\fR considers the strings equal if the first \fIn\fR characters match. + +\fBstr_equal\fR returns 1, if \fIs\fR and \fIt\fR match up to and including the +first occurance of \\0 or returns 0 otherwise. It is the opposite of \fBstr_diff\fR. + +\fBstr_start\fR compares the two strings from the begining. +It returns 1 if \fIt\fR is a prefix of \fIs\fR or 0 otherwise. + +\fB*str_append\fR appends a single byte \fIs\fR to \fIout\fR given \fIout\fR +is allocated with enough space. +.SH "NOTE" +For the \fBstr_copy*\fR and \fB*str_append\fP commands \fIdst\fR +has to have a preallocated space. +Otherwise the result may be unexpected. +.SH "SEE ALSO" +byte(3), stralloc(3) diff --git a/man/stralloc.3 b/man/stralloc.3 new file mode 100644 index 0000000..55da25d --- /dev/null +++ b/man/stralloc.3 @@ -0,0 +1,160 @@ +.TH qlibs stralloc 3 +.SH NAME +stralloc \- dynamically allocated strings +.SH SYNTAX +.B #include \(dqstralloc.h\(dq + +int \fBstralloc_ready\fP(&\fIsa\fR,\fIlen\fR); +.br +int \fBstralloc_readyplus\fP(&\fIsa\fR,\fIlen\fR); + +int \fBstralloc_copy\fP(&\fIsa\fR,&\fIsa2\fR); +.br +int \fBstralloc_copys\fP(&\fIsa\fR,\fIbuf\fR); +.br +int \fBstralloc_copyb\fP(&\fIsa\fR,\fIbuf\fR,\fIlen\fR); + +int \fBstralloc_cat\fP(&\fIsa\fR,&\fIsa2\fR); +.br +int \fBstralloc_cats\fP(&\fIsa\fR,\fIbuf\fR); +.br +int \fBstralloc_catb\fP(&\fIsa\fR,\fIbuf\fR,\fIlen\fR); + +int \fBstralloc_append\fP(&\fIsa\fR,\fIbuf\fR); +.br +int \fBstralloc_0\fP(&\fIsa\fR); + +int \fBstralloc_starts\fP(&\fIsa\fR,\fIbuf\fR); + +stralloc \fIsa\fR = {0}; +.br +stralloc \fIsa2\fR = {0}; +.br +unsigned int \fIlen\fR; +.br +char *\fIbuf\fR; +.SH DESCRIPTION +A +.B stralloc +variable holds a string in dynamically allocated space. +String length is limited only by memory. +String contents are unrestricted. + +The +.B stralloc +structure has three components: +.I sa\fB.s +is a pointer to the string, or 0 if it is not allocated; +.I sa\fB.len +is the number of bytes in the string, if it is allocated; +.I sa\fB.a +is the number of bytes allocated for the string, if it is allocated. +A +.B stralloc +variable should be initialized to {0}, +meaning unallocated. + +.B stralloc_ready +makes sure that +.I sa +has enough space allocated for +.I len +characters. +It allocates extra space if necessary. + +.B stralloc_readyplus +makes sure that +.I sa +has enough space allocated for +.I len +characters more than its current length. +If +.I sa +is unallocated, +.B stralloc_readyplus +is the same as +.BR stralloc_ready . + +.B stralloc_copy +copies +.I sa2 +to +.IR sa , +allocating space if necessary. +Here +.I sa2 +is an allocated +.B stralloc +variable. + +.B stralloc_copys +copies a 0-terminated string, +.IR buf , +to +.IR sa , +without the 0. + +.B stralloc_copyb +copies +.I len +characters from +.I buf +to +.IR sa . + +.B stralloc_cat +appends +.I sa2 +to +.IR sa , +allocating space if necessary. +If +.I sa +is unallocated, +.B stralloc_cat +is the same as +.BR stralloc_copy . + +.B stralloc_cats +and +.B stralloc_catb +are analogous to +.B stralloc_copys +and +.BR stralloc_copyb . + +.B stralloc_append +adds a single character, +.IR *buf , +to +.IR sa , +allocating space if necessary. + +.B stralloc_0 +adds a single 0 character +to +.IR sa . + +.B stralloc_starts +returns 1 if the 0-terminated string +.IR buf , +without the 0, +is a prefix of +.IR sa . +.SH "ERROR HANDLING" +If a +.B stralloc +routine runs out of memory, +it leaves +.I sa +alone and returns 0, +setting +.B errno +appropriately. +On success it returns 1; +this guarantees that +.I sa +is allocated. +.SH "SEE ALSO" +alloc(3), +error(3) diff --git a/man/taia.3 b/man/taia.3 new file mode 100644 index 0000000..0aeb4e0 --- /dev/null +++ b/man/taia.3 @@ -0,0 +1,91 @@ +.TH taia 3 +.SH NAME +taia \- Temps Atomique International (Attosecond) time routines +.SH SYNTAX +.B #include \(dqtaia.h\(dq + +extern int \fBtaia_add\fP(struct taia *\fIt\fR,const struct taia *\fIa\fR,const struct taia *\fIb\fR); +.br +extern int \fBtaia_addsec\fP(struct taia *\fIt\fR,const struct taia *\fIs\fR,int \fIsecs\fR); +.br +extern int \fBtaia_approx\fP(const struct taia *\fIt\fR); +.br +int \fBtaia_frac\fP(const struct taia *\fIt\fR); +.br +extern int \fBtaia_less\fP(const struct tai *\fIa\fR,const struct tai *\fIb\fR); +.br +extern int \fBtaia_now\fP(struct taia *\fIt\fR); +.br +extern int \fBtaia_pack\fP(char *buf,const struct taia *\fIt\fR); +.br +extern int \fBtaia_sub\fP(struct taia *\fIt\fR,const struct taia *\fIa\fR,const struct taia *\fIb\fR); +.br +extern int \fBtaia_tai\fP(const struct taia *\fIt\fR,struct tai *\fIsec\fR); +.br +extern int \fBtaia_uint\fP(struct taia *\fIt\fR,unsigned int \fIsecs\fR); +.br +extern int \fBtaia_unpack\fP(const char *buf,struct taia *\fIt\fR); +.SH DESCRIPTION +.B taia_add +adds \fIa\fR to \fIb\fR and writes the result to \fIt\fR. +The inputs and output may overlap. + +.B taia_addsec +adds \fIsecs\fR seconds to \fIs\fR and writes the result to \fIt\fR. +The inputs and output may overlap. + +.B taia_approx +returns a double-precision approximation of \fIt\fR. +The result of +.B taia_approx +is always nonnegative. + +.B taia_frac +returns a double-precision approximation to the fraction part +of \fIt\fR. The result of +.B taia_frac +is always nonnegative. + +.B taia_less +returns 1 if \fIa\fR is less than \fIb\fR, 0 otherwise. + +.B taia_now +puts the current time into \fIt\fR. More precisely: +.B tai_now +puts into \fIt\fR its best guess as to the TAI64NA label +for the 1-attosecond interval that contains the current time. + +This implementation of taia_now assumes that the +.I time_t +returned from the time function represents the number of TAI seconds since 1970-01-01 +00:00:10 TAI. This matches the convention used by the Olson tz library +in ``right'' mode. + +Beware that many clocks are not set accurately, and even the best +scientific clocks are nowhere near 1-attosecond accuracy; however, an +inaccurate clock may still produce reasonably accurate time differences. + +.B taia_pack +converts a TAI64NA label from internal format in \fIt\fR to external +TAI64NA format in \fIbuf\fR. + +.B taia_sub +subtracts \fIb\fR from \fIa\fR and writes the result to \fIt\fR. +The inputs and output may overlap. + +.B taia_tai +places into \fIsec\fR the integer part of \fIt\fR. If \fIt\fR +contains a TAI64NA label then \fIsec\fR will contain the corresponding +TAI64 label. + +.B taia_uint +converts \fIsecs\fR into a struct taia (setting the fractional part to zero). + +.B taia_unpack +converts a TAI64NA label from external TAI64NA format in +\fIbuf\fR to internal format in \fIt\fR. +.SH "SEE ALSO" +time(1), +utime(3), +ctime(3), +locale(1) diff --git a/man/timeout.3 b/man/timeout.3 new file mode 100644 index 0000000..6113f27 --- /dev/null +++ b/man/timeout.3 @@ -0,0 +1,36 @@ +.TH qlibs: timeout 3 +.SH NAME +timeout \- reading from and writing to a file descriptor +.SH SYNTAX +.B #include \(dqtimeout.h\(dq + +int \fBtimeoutread\fP(int \fIt\fR,int \fIfd\fR,char *\fIbuf\fR,int \fIlen\fR); +.br +int \fBtimeoutwrite\fP(int,int,char *,int); +.SH DESCRIPTION +.B timeoutread +reads from file descriptor +.I fd +.I len +bytes into +.I buf +returning +.I 0 +on success and +.I -1 +in case a timeout has occured. +.B timeoutwrite +writes to file descriptor +.I fd +.I len +bytes from +.I buf +returning +.I 0 +on success and +.I -1 +in case a timeout has occured. +.SH "SEE ALSO" +wait(3), +timeoutconn(3) +taia(3). diff --git a/man/timeoutconn.3 b/man/timeoutconn.3 new file mode 100644 index 0000000..dad9e95 --- /dev/null +++ b/man/timeoutconn.3 @@ -0,0 +1,52 @@ +.TH qlibs: timeoutconn 3 +.SH NAME +timeoutconn \- set up an outoing stream socket for IPv4/IPv6 +.SH SYNTAX +.B #include \(dqtimeoutconn.h\(dq + +int \fBtimeoutconn4\fP(int \fIs\fR,char \fIip[4]\fR,uint16 \fIp\fR,unsigned int \fIt\fR); +.br +int \fBtimeoutconn6\fP(int \fIs\fR,char \fIip[16]\fR,uint16 \fIp\fR,unsigned int \fIt\fR,uint32 \fInetif\fR); +.br +int \fBtimeoutconn\fP(int \fIs\fR,char \fIip[16]\fR,uint16 \fIp\fR,unsigned int \fIt\fR,uint32 \fInetif\fR); +.SH DESCRITPION +.B timeoutconn +tries to establish a TCP stream socket to address +.I ip +on remoteport +.I p +and waiting for +.I t +seconds and on success returns the +.I s +socket identifier. + +In case +.I addresss +is an IPv6 LLU address, one needs to define the +.I netif +interface index, otherwise +.I 0 +is the default. +.SH INTERNALS +.B timeoutconn +depends on +.B taia +and +.B iopuase +to determine the timespan and perhaps +.B ndelay +to succeed. +.SH RETURN CODES +.B timeoutconn +returns +.I 0 +if the connection is established +and +.I -1 +if an error has occured. +.SH SEE ALSO +socket_if(3), +timeout(3) +taia(3), +wait(3) diff --git a/man/wait.3 b/man/wait.3 new file mode 100644 index 0000000..c3b6c63 --- /dev/null +++ b/man/wait.3 @@ -0,0 +1,96 @@ +.TH qlibs: wait 3 +.SH NAME +wait \- check child process status +.SH SYNTAX +.B #include \(dqwait.h\(dq + +int \fBwait_nohang\fP(&\fIwstat\fR); +.br +int \fBwait_stop\fP(&\fIwstat\fR); +.br +int \fBwait_stopnohang\fP(&\fIwstat\fR); +.br +int \fBwait_pid\fP(&\fIwstat\fR,\fIpid\fR); + +int \fBwait_exitcode\fP(\fIwstat\fR); +.br +int \fBwait_crashed\fP(\fIwstat\fR); +.br +int \fBwait_stopped\fP(\fIwstat\fR); +.br +int \fBwait_stopsig\fP(\fIwstat\fR); + +int \fIpid\fR; +.br +int \fIwstat\fR; +.SH DESCRIPTION +.B wait_nohang +looks for zombies (child processes that have exited). +If it sees a zombie, +it eliminates the zombie, +puts the zombie's exit status into +.IR wstat , +and returns the zombie's process ID. +If there are several zombies, +.B wait_nohang +picks one. +If there are children but no zombies, +.B wait_nohang +returns +.IR 0 . +If there are no children, +.B wait_nohang +returns +.IR -1 , +setting +.B errno +appropriately. + +.B wait_stopnohang +is similar to +.BR wait_nohang , +but it also looks for children that have stopped. + +.B wait_stop +is similar to +.BR wait_stopnohang , +but if there are children it will pause waiting for one of them +to stop or exit. + +.B wait_pid +waits for child process +.I pid +to exit. +It eliminates any zombie that shows up in the meantime, +discarding the exit status. + +.B wait_stop +and +.B wait_pid +retry upon +.BR error_intr . +.SH "STATUS PARSING" +If the child stopped, +.B wait_stopped +is nonzero; +.B wait_stopsig +is the signal that caused the child to stop. + +If the child exited by crashing, +.B wait_stopped +is zero; +.B wait_crashed +is nonzero. + +If the child exited normally, +.B wait_stopped +is zero; +.B wait_crashed +is zero; +and +.B wait_exitcode +is the child's exit code. +.SH "SEE ALSO" +pathexec(3), +wait(2), +error(3) diff --git a/man/x.html b/man/x.html new file mode 100644 index 0000000..224edc1 --- /dev/null +++ b/man/x.html @@ -0,0 +1,99 @@ +<HTML> +<BODY> +<PRE> +<!-- Manpage converted by man2html 3.0.1 --> +[1mSYNTAX[0m + [1m#include "logmsg.h"[0m + + int logmsg(const char *who, int ecode, unsigned int classs, char *msg) + + [1merr_sys[22m(w,e) logmsg(w,e,FATAL,"") + [1merr_sys_plus[22m(w,e,m) logmsg(w,e,FATAL,m) + [1merr_tmp[22m(w,e) logmsg(w,e,WARN,"") + [1merr_tmp_plus[22m(w,e,m) logmsg(w,e,WARN,m) + [1merr_int[22m(w,e,c) logmsg(w,e,c,"") + [1merr_int_plus[22m(w,e,c,m) logmsg(w,e,c,m) + [1mlog_who[22m(w,m) logmsg(w,0,LOG,m) + [1mlog_anon[22m(m) logmsg("",0,LOG,m) + +[1mDESCRIPTION[0m + [1mlogmsg [22mprints error, warning, or info/logging messages to stderr and + potentially terminates the calling program, depending on the [4mclass[0m + given. [4mwho[24m is the name of the program, [4mecode[24m is an error code, [4mclass[0m + determines the behavior upon call and [4mmsg[24m is the logging message. Read + "error.h" to learn more about related constants. + +[1mECODE[0m + [4mecode[24m is the error code and subject to be displayed in the log file and + potentially used upon exit if the [4mclass[24m equals [1mERROR[22m, [1mFATAL[22m, or [1mDROP[22m. + + To avoid conflicts with syscall error codes, appplication defined error + codes should be negative. The values [4m-15[24m, [4m-100[24m and [4m-111[24m are reserved + for backward compatibility. + +[1mCLASS[0m + The [4mclass[24m [4mparameter[24m [4mindicates[24m [4mhow[24m [4mthe[24m [4mapplication[24m [4mhandles[24m [4mexceptions[0m + [4mand[24m [4mdisplays[24m [4mthe[24m [4mlog[24m [4mmessage.[0m + + [4mo[24m [1mLOG[22m, [1mINFO[22m, [1mALERT[22m, [1mWARN [22m- display message and continue operation + + o [1mDROP [22m- display warning message and continue while returning to the + calling program + + o [1mUSAGE[22m, [1mSYNTAX[22m, [1mFATAL[22m, [1mERROR [22m- display error message and exit appli‐ + cation with error code + + [1mINFO[22m, [1mALERT[22m, [1mWARN[22m, [1mDROP[22m, [1mUSAGE[22m, and [1mFATAL [22mas well as [1mERROR [22mdisplay the + respective class string like [4mwarning:[24m in the log message, while [1mLOG[0m + shows the log message only. + + The class [1mFATAL [22mshould be used for system error codes only, rather [1mER‐[0m + [1mROR [22mand [1mWARN [22mshall be set in conjunction with an application er‐ + ror/warning. + +[1mMESSAGE[0m + If the custom message [4mmsg[24m is given, it will be printed additionally. + + Dan Bernstein used sets of [4mstrerr_dieY*()[24m and [4mstrerr_warnY()[24m messages + which explicitely determine the message and behavior class. Other + classes were occasionally defined on demand, such als [4musage()[24m. + + Kai Peter introduced the [4merrmsg[24m facility in his [1mqlibs [22mincluding a [1msys‐[0m + [1mlog [22mcompliant [4mseverity[24m as second parameter. + +[1mEXAMPLES[0m + The macro definitions uses [1mw [22mfor the calling program, [1me [22mfor error + code, [1mc [22mfor class, and [1mm [22mfor message. + + #include "logmsg.h" + #define WHO "my_prog" + + err_sys(WHO,errno); + err_sys_plus(WHO,-111,"additional message"); + + err_tmp("",-100); + err_tmp_plus("",errno,"additional message"); + + log_who(WHO,"message"); + + log_anon() is like log_who() but doesn't print the caller name. + + An user defined message [1ms [22mcan be build from multiple arguments by using + the [4mB[24m (build) macro: + + err_sys_plus((errno),B("unable to run: ",*argv)); + +[1mSEE ALSO[0m + <B>syslog(3)</B> + + + + 3 qlibs:(logmsg) +</PRE> +<HR> +<ADDRESS> +Man(1) output converted with +<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a> +</ADDRESS> +</BODY> +</HTML> |