1.\"	$OpenBSD: cgetent.3,v 1.2 2021/02/02 07:33:29 jmc Exp $
2.\"
3.\" Copyright (c) 1992, 1993
4.\"	The Regents of the University of California.  All rights reserved.
5.\"
6.\" This code is derived from software contributed to Berkeley by
7.\" Casey Leedom of Lawrence Livermore National Laboratory.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\" 3. Neither the name of the University nor the names of its contributors
18.\"    may be used to endorse or promote products derived from this software
19.\"    without specific prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.Dd $Mdocdate: February 2 2021 $
34.Dt CGETENT 3
35.Os
36.Sh NAME
37.Nm cgetent ,
38.Nm cgetset ,
39.Nm cgetmatch ,
40.Nm cgetcap ,
41.Nm cgetnum ,
42.Nm cgetstr ,
43.Nm cgetustr ,
44.Nm cgetfirst ,
45.Nm cgetnext ,
46.Nm cgetclose ,
47.Nm cgetusedb
48.Nd capability database access routines
49.Sh SYNOPSIS
50.In stdlib.h
51.Ft int
52.Fn cgetent "char **buf" "char **db_array" "const char *name"
53.Ft int
54.Fn cgetset "const char *ent"
55.Ft int
56.Fn cgetmatch "char *buf" "const char *name"
57.Ft char *
58.Fn cgetcap "char *buf" "const char *cap" "int type"
59.Ft int
60.Fn cgetnum "char *buf" "const char *cap" "long *num"
61.Ft int
62.Fn cgetstr "char *buf" "const char *cap" "char **str"
63.Ft int
64.Fn cgetustr "char *buf" "const char *cap" "char **str"
65.Ft int
66.Fn cgetfirst "char **buf" "char **db_array"
67.Ft int
68.Fn cgetnext "char **buf" "char **db_array"
69.Ft int
70.Fn cgetclose "void"
71.Ft int
72.Fn cgetusedb "int usedb"
73.Sh DESCRIPTION
74The
75.Fn cgetent
76function extracts the capability record
77.Fa name
78from the database specified by the null-terminated
79file array
80.Fa db_array
81and returns a pointer to a
82copy of it in
83.Fa buf .
84.Fn cgetent
85will first look for files ending in
86.Dq .db
87(see
88.Xr cap_mkdb 1 )
89before accessing the
90.Tn ASCII
91version of the capability database.
92.Fa buf
93must be retained through all subsequent calls to
94.Fn cgetmatch ,
95.Fn cgetcap ,
96.Fn cgetnum ,
97.Fn cgetstr ,
98and
99.Fn cgetustr ,
100but may then be
101.Xr free 3 Ns \&'d.
102On success 0 is returned, 1 if the returned
103record contains an unresolved
104.Ic tc
105expansion,
106\-1 if the requested record couldn't be found,
107\-2 if a system error occurred (couldn't open or read a file,
108for example) also
109setting
110.Va errno ,
111and \-3 if a potential reference loop is detected (see
112.Ic tc=
113comments below).
114.Pp
115.Fn cgetset
116enables the addition of a character buffer containing a single capability
117record entry
118to the capability database.
119Conceptually, the entry is added as the first
120.Dq file
121in the database, and
122is therefore searched first on the call to
123.Fn cgetent .
124The entry is passed in
125.Fa ent .
126If
127.Fa ent
128is
129.Dv NULL ,
130the current entry is removed from the database.
131.Fn cgetset
132must precede the database traversal.
133It must be called before
134.Fn cgetent .
135If a sequential access is being performed (see below), it must be called
136before the first sequential access call
137.Pf ( Fn cgetfirst
138or
139.Fn cgetnext ) ,
140or be directly preceded by a
141.Fn cgetclose
142call.
143On success 0 is returned and \-1 on failure.
144.Pp
145.Fn cgetmatch
146will return 0 if
147.Fa name
148is one of the names of the capability record
149.Fa buf ,
150\-1 if
151not.
152.Pp
153.Fn cgetcap
154searches the capability record
155.Fa buf
156for the capability
157.Fa cap
158with type
159.Fa type .
160A
161.Fa type
162is specified using any single character.
163If a colon
164.Pq Sq \&:
165is used, an
166untyped capability will be searched for (see below for explanation of
167types).
168A pointer to the value of
169.Fa cap
170in
171.Fa buf
172is returned on success or
173.Dv NULL
174if the requested capability couldn't be
175found.
176The end of the capability value is signaled by a
177.Sq \&:
178or
179.Tn ASCII
180NUL
181(see below for capability database syntax).
182.Pp
183.Fn cgetnum
184retrieves the value of the numeric capability
185.Fa cap
186from the capability record pointed to by
187.Fa buf .
188The numeric value is returned in the
189.Ft long
190pointed to by
191.Fa num .
192On success 0 is returned, \-1 if the requested numeric capability couldn't
193be found.
194.Pp
195.Fn cgetstr
196retrieves the value of the string capability
197.Fa cap
198from the capability record pointed to by
199.Fa buf .
200A pointer to a decoded, NUL-terminated,
201.Xr malloc 3 Ns \&'d
202copy of the string is returned in the
203.Ft char *
204pointed to by
205.Fa str .
206The number of characters in the decoded string (not including the trailing
207NUL) is returned on success, \-1 if the requested string capability couldn't
208be found, or \-2 if a system error was encountered (storage allocation
209failure).
210.Pp
211.Fn cgetustr
212is identical to
213.Fn cgetstr
214except that it does not expand special characters, but rather returns each
215character of the capability string literally.
216.Pp
217.Fn cgetfirst
218and
219.Fn cgetnext
220comprise a function group that provides for sequential
221access of the null-terminated array of file names,
222.Fa db_array .
223.Fn cgetfirst
224returns the first record in the database and resets the access
225to the first record.
226.Fn cgetnext
227returns the next record in the database with respect to the
228record returned by the previous
229.Fn cgetfirst
230or
231.Fn cgetnext
232call.
233If there is no such previous call, the first record in the database is
234returned.
235Each record is returned in a
236.Xr malloc 3 Ns \&'d
237copy pointed to by
238.Fa buf .
239.Ic tc
240expansion is done (see
241.Ic tc=
242comments below).
243Upon completion of the database 0 is returned; 1 is returned upon successful
244return of a record with possibly more remaining (the end of the database has
245not been reached yet); 2 is returned if the record contains an unresolved
246.Ic tc
247expansion; \-1 is returned if a system error occurred; and \-2
248is returned if a potential reference loop is detected (see
249.Ic tc=
250comments below).
251Upon completion of database (0 return), the database is closed.
252.Pp
253.Fn cgetclose
254closes the file descriptor and resets state used for sequential access.
255If neither the
256.Fn cgetfirst
257nor the
258.Fn cgetnext
259functions have been called,
260.Fn cgetclose
261has no effect.
262Note that it does not erase the buffer pushed by a call to
263.Fn cgetset ,
264nor does it free the buffer allocated by
265.Fn cgetent .
266.Pp
267.Fn cgetusedb
268allows the user to specify whether to use or ignore database files ending in
269.Dq .db .
270If
271.Ar usedb
272is zero, files ending in
273.Dq .db
274will be ignored.
275If
276.Ar usedb
277is non-zero, files ending in
278.Dq .db
279will be used in preference to the text version.
280The default is to process
281.Dq .db
282files.
283.Fn cgetusedb
284returns the previous setting.
285.Ss Capability database syntax
286Capability databases are normally
287.Tn ASCII
288and may be edited with standard
289text editors.
290Blank lines and lines beginning with a
291.Sq \&#
292are comments and are ignored.
293Lines ending with a
294.Sq \|\e
295indicate that the next line is a continuation of the current line; the
296.Sq \|\e
297and following newline are ignored.
298Long lines are usually continued onto several physical
299lines by ending each line except the last with a
300.Sq \|\e .
301.Pp
302Capability databases consist of a series of records, one per logical
303line.
304Each record contains a variable number of colon-separated fields
305(capabilities).
306Empty fields consisting entirely of whitespace
307characters (spaces and tabs) are ignored.
308.Pp
309The first capability of each record specifies its names, separated by
310.Sq \&|
311characters.
312These names are used to reference records in the database.
313By convention, the last name is usually a comment and is not intended as
314a lookup tag.
315For example, the
316.Dq vt220
317record from the
318.Nm termcap
319database begins with
320.Pp
321.Dl "vt220\||\|vt200\||\|dec vt220:"
322.Pp
323giving two names that can be used to access this record.
324.Pp
325The remaining non-empty capabilities describe a set of (name, value)
326bindings, consisting of a name optionally followed by a typed value:
327.Bl -column "nameTvalue" -offset indent
328.It name Ta "typeless [boolean] capability"
329.Em name No "is present [true]"
330.It name Ns Em \&T Ns value Ta capability
331.Pq Em name , \&T
332has value
333.Em value
334.It name@ Ta "no capability" Em name No exists
335.It name Ns Em T Ns \&@ Ta capability
336.Pq Em name , T
337does not exist
338.El
339.Pp
340Names consist of one or more characters.
341Names may contain any character except
342.Sq \&: ,
343but it's usually best to restrict them to the printable
344characters and avoid use of graphics like
345.Sq \&# ,
346.Sq \&= ,
347.Sq \&% ,
348.Sq \&@ ,
349etc.
350Types are single characters used to separate capability names from their
351associated typed values.
352Types may be any character except a
353.Sq \&: .
354Typically, graphics like
355.Sq \&# ,
356.Sq \&= ,
357.Sq \&% ,
358etc. are used.
359Values may be any number of characters and may contain any character except
360.Sq \&: .
361.Ss Capability database semantics
362Capability records describe a set of (name, value) bindings.
363Names may have multiple values bound to them.
364Different values for a name are distinguished by their
365.Fa types .
366.Fn cgetcap
367will return a pointer to a value of a name given the capability name and
368the type of the value.
369.Pp
370The types
371.Sq \&#
372and
373.Sq \&=
374are conventionally used to denote numeric and
375string typed values, but no restriction on those types is enforced.
376The functions
377.Fn cgetnum
378and
379.Fn cgetstr
380can be used to implement the traditional syntax and semantics of
381.Sq \&#
382and
383.Sq \&= .
384Typeless capabilities are typically used to denote boolean objects with
385presence or absence indicating truth and false values respectively.
386This interpretation is conveniently represented by:
387.Pp
388.Dl "(cgetcap(buf, name, ':') != NULL)"
389.Pp
390A special capability,
391.Ic tc= name ,
392is used to indicate that the record specified by
393.Fa name
394should be substituted for the
395.Ic tc
396capability.
397.Ic tc
398capabilities may interpolate records which also contain
399.Ic tc
400capabilities and more than one
401.Ic tc
402capability may be used in a record.
403A
404.Ic tc
405expansion scope (i.e., where the argument is searched for) contains the
406file in which the
407.Ic tc
408is declared and all subsequent files in the file array.
409.Pp
410When a database is searched for a capability record, the first matching
411record in the search is returned.
412When a record is scanned for a
413capability, the first matching capability is returned; the capability
414.Ic :nameT@:
415will hide any following definition of a value of type
416.Em T
417for
418.Fa name ;
419and the capability
420.Ic :name@:
421will prevent any following values of
422.Fa name
423from being seen.
424.Pp
425These features combined with
426.Ic tc
427capabilities can be used to generate variations of other databases and
428records by either adding new capabilities, overriding definitions with new
429definitions, or hiding following definitions via
430.Sq \&@
431capabilities.
432.Ss cgetnum() and cgetstr() syntax and semantics
433Two types are predefined by
434.Fn cgetnum
435and
436.Fn cgetstr :
437.Bl -column "nameXnumber" -offset indent
438.It Em name Ns \&# Ns Em number Ta numeric
439capability
440.Em name
441has value
442.Em number
443.It Em name Ns = Ns Em string Ta "string capability"
444.Em name
445has value
446.Em string
447.It Em name Ns \&#@ Ta "the numeric capability"
448.Em name
449does not exist
450.It Em name Ns \&=@ Ta "the string capability"
451.Em name
452does not exist
453.El
454.Pp
455Numeric capability values may be given in one of three numeric bases.
456If the number starts with either
457.Ql 0x
458or
459.Ql 0X
460it is interpreted as a hexadecimal number (both upper and lower case a-f
461may be used to denote the extended hexadecimal digits).
462Otherwise, if the number starts with a
463.Ql 0
464it is interpreted as an octal number.
465Otherwise the number is interpreted as a decimal number.
466.Pp
467String capability values may contain any character.
468Non-printable
469.Dv ASCII
470codes, new lines, and colons may be conveniently represented by the use
471of escape sequences:
472.Bl -column "\e\|X,X\e\|X" "(ASCII octal nnn)" -offset indent
473.It ^X	('\fIX\fP'\~&\~037)	control-\fIX\fP
474.It \e\|b,\~\e\|B	(ASCII\~010)	backspace
475.It \e\|t,\~\e\|T	(ASCII\~011)	tab
476.It \e\|n,\~\e\|N	(ASCII\~012)	line\~feed\~(newline)
477.It \e\|f,\~\e\|F	(ASCII\~014)	form\~feed
478.It \e\|r,\~\e\|R	(ASCII\~015)	carriage\~return
479.It \e\|e,\~\e\|E	(ASCII\~027)	escape
480.It \e\|c,\~\e\|C	(:)	colon
481.It \e\|\e	(\e\|)	backslash
482.It \e\|^	(^)	caret
483.It \e\|\fInnn\fP	(ASCII\~octal\~\fInnn\fP)
484.El
485.Pp
486A
487.Sq \|\e
488followed by up to three octal digits directly specifies
489the numeric code for a character.
490The use of
491.Tn ASCII
492NULs, while easily
493encoded, causes all sorts of problems and must be used with care since
494NULs are typically used to denote the end of strings; many applications
495use
496.Sq \e\|200
497to represent a NUL.
498.Sh EXAMPLES
499.Bd -unfilled -offset indent
500example\||\|an example of binding multiple values to names:\e
501	:foo%bar:foo^blah:foo@:\e
502	:abc%xyz:abc^frap:abc$@:\e
503	:tc=more:
504.Ed
505.Pp
506The capability foo has two values bound to it (bar of type
507.Sq \&%
508and blah of
509type
510.Sq \&^ )
511and any other value bindings are hidden.
512The capability abc also has two values bound but only a value of type
513.Sq \&$
514is prevented from
515being defined in the capability record more.
516.Bd -unfilled -offset indent
517file1:
518 	new\||\|new_record\||\|a modification of "old":\e
519		:fript=bar:who-cares@:tc=old:blah:tc=extensions:
520file2:
521	old\||\|old_record\||\|an old database record:\e
522		:fript=foo:who-cares:glork#200:
523.Ed
524.Pp
525The records are extracted by calling
526.Fn cgetent
527with file1 preceding file2.
528In the capability record new in file1, fript=bar overrides the definition
529of fript=foo interpolated from the capability record old in file2,
530who-cares@ prevents the definition of any who-cares definitions in old
531from being seen, glork#200 is inherited from old, and blah and anything
532defined by the record extensions is added to those definitions in old.
533Note that the position of the fript=bar and who-cares@ definitions before
534tc=old is important here.
535If they were after, the definitions in old would take precedence.
536.Sh DIAGNOSTICS
537.Fn cgetent ,
538.Fn cgetset ,
539.Fn cgetmatch ,
540.Fn cgetnum ,
541.Fn cgetstr ,
542.Fn cgetustr ,
543.Fn cgetfirst ,
544and
545.Fn cgetnext
546return a value greater than or equal to 0 on success and a value less
547than 0 on failure.
548.Fn cgetcap
549returns a character pointer on success and a
550.Dv NULL
551on failure.
552.Pp
553.Fn cgetent
554and
555.Fn cgetset
556may fail and set
557.Va errno
558for any of the errors specified for the library functions
559.Xr fopen 3 ,
560.Xr fclose 3 ,
561.Xr open 2 ,
562and
563.Xr close 2 .
564.Pp
565.Fn cgetent ,
566.Fn cgetset ,
567.Fn cgetstr ,
568and
569.Fn cgetustr
570may fail and set
571.Va errno
572as follows:
573.Bl -tag -width Er
574.It Bq Er ENOMEM
575No memory to allocate.
576.El
577.Sh SEE ALSO
578.Xr cap_mkdb 1 ,
579.Xr malloc 3
580.Sh BUGS
581Colon
582.Pq Sq \&:
583characters
584or vertical bar
585.Pq Sq |
586characters cannot be used in names.
587.Pp
588There are no checks for
589.Ic tc= name
590loops in
591.Fn cgetent .
592.Pp
593The buffer added to the database by a call to
594.Fn cgetset
595is not unique to the database but is rather prepended to any database used.
596