xref: /freebsd/contrib/mandoc/catman.8 (revision 24e4dcf4ba5e9dedcf89efd358ea3e1fe5867020)
1.\" $Id: catman.8,v 1.15 2025/07/13 14:15:26 schwarze Exp $
2.\"
3.\" Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: July 13 2025 $
18.Dt CATMAN 8
19.Os
20.Sh NAME
21.Nm catman
22.Nd format all manual pages below a directory
23.Sh SYNOPSIS
24.Nm catman
25.Op Fl I Cm os Ns = Ns Ar name
26.Op Fl T Ar output
27.Ar srcdir dstdir
28.Sh DESCRIPTION
29The
30.Nm
31utility assumes that all files below
32.Ar srcdir
33are manual pages in
34.Xr mdoc 7
35and
36.Xr man 7
37format and formats all of them, storing the formatted versions in
38the same relative paths below
39.Ar dstdir .
40Unless they already exist,
41.Ar dstdir
42itself and any required subdirectories are created.
43Existing files are not explicitly deleted, but possibly overwritten.
44.Pp
45The options are as follows:
46.Bl -tag -width Ds
47.It Fl I Cm os Ns = Ns Ar name
48Override the default operating system
49.Ar name
50for the
51.Xr mdoc 7
52.Ic \&Os
53and for the
54.Xr man 7
55.Ic TH
56macro.
57.It Fl T Ar output
58Output format.
59The
60.Ar output
61argument can be
62.Cm ascii ,
63.Cm utf8 ,
64or
65.Cm html ;
66see
67.Xr mandoc 1 .
68In
69.Cm html
70output mode, the
71.Cm fragment
72output option is implied.
73Other output options are not supported.
74.It Fl v
75Verbose mode, printing additional information to standard error output.
76Specifying this once prints a summary about the number of files
77and directories processed at the end of the iteration.
78Specifying it twice additionally prints debugging information
79about the backchannel from
80.Xr mandocd 8
81to
82.Nm
83that is used to limit the number of files in flight at any given time.
84For details, see
85.Sx DIAGNOSTICS .
86.El
87.Sh IMPLEMENTATION NOTES
88Since this version avoids
89.Xr fork 2
90and
91.Xr exec 3
92overhead and uses the much faster
93.Sy mandoc
94parsers and formatters rather than
95.Sy groff ,
96it may be about one order of magnitude faster than other
97.Nm
98implementations.
99.Sh EXIT STATUS
100.Ex -std
101.Pp
102Failures while trying to open individual manual pages for reading,
103to save individual formatted files to the file system,
104or even to read or create subdirectories do not cause
105.Nm
106to return an error exit status.
107In such cases,
108.Nm
109simply continues with the next file or subdirectory.
110.Sh DIAGNOSTICS
111Some fatal errors cause
112.Nm
113to exit before the iteration over input files is even started:
114.Bl -tag -width Ds -offset indent
115.It unknown option \-\- Ar option
116An invalid option was passed on the command line.
117.It missing arguments: srcdir and dstdir
118No argument was provided.
119Both
120.Ar srcdir
121and
122.Ar dstdir
123are mandatory.
124.It missing argument: dstdir
125Only one argument was provided.
126The second argument,
127.Ar dstdir ,
128is mandatory, too.
129.It too many arguments: Ar third argument
130Three or more arguments were provided, but only two are supported.
131.It Sy socketpair : Ar reason
132The sockets needed for communication with
133.Xr mandocd 8
134could not be created, for example due to file descriptor or memory exhaustion.
135.It Sy fork : Ar reason
136The new process needed to run
137.Xr mandocd 8
138could not be created, for example due to process table exhaustion
139or system resource limits.
140.It Sy exec Ns Po Sy mandocd Pc : Ar reason
141The
142.Xr mandocd 8
143child program could not be started, for example because it is not in the
144.Ev PATH
145or has no execute permission.
146.It Sy mkdir No destination Ar dstdir : reason
147The
148.Ar dstdir
149does not exist and could not be created, for example because
150the parent directory does not exist or permission is denied.
151.It Sy open No destination Ar dstdir : reason
152The
153.Ar dstdir
154could not be opened for reading, for example because
155it is not a directory or permission is denied.
156.It Sy chdir No to source Ar srcdir : reason
157The current working directory could not be changed to
158.Ar srcdir ,
159for example because it does not exist, it is not a directory,
160or permission is denied.
161.It Sy fts_open : Ar reason
162Starting the iteration was attempted but failed,
163for example due to memory exhaustion.
164.El
165.Pp
166Some fatal errors cause the iteration over input files to be aborted
167prematurely:
168.Bl -tag -width Ds -offset indent
169.It FATAL: Sy fts_read : Ar reason
170A call to
171.Xr fts_read 3
172returned
173.Dv NULL ,
174meaning that the iteration failed before being complete.
175.It FATAL: mandocd child died: got Ar SIGNAME
176This message appears if
177.Nm
178gets the
179.Dv SIGCHLD
180or
181.Dv SIGPIPE
182signal, most likely due to a fatal bug in
183.Xr mandocd 8 .
184.It FATAL: Sy sendmsg : Ar reason
185The file descriptors needed to process one of the manual pages
186could not be sent to
187.Xr mandocd 8 ,
188for example because
189.Xr mandocd 8
190could not be started or died unexpectedly.
191.It FATAL: Sy recv : Ar reason
192Trying to read a reply message from
193.Xr mandocd 8
194failed, most likely because
195.Xr mandocd 8
196unexpectedly died or closed the socket.
197.It FATAL: signal Ar SIGNAME
198This message appears if
199.Nm
200gets a
201.Dv SIGHUP ,
202.Dv SIGINT ,
203or
204.Dv SIGTERM
205signal, for example because the user deliberately killed it.
206.El
207.Pp
208Some non-fatal errors cause a single subdirectory to be skipped.
209The iteration is not aborted but continues with the next subdirectory,
210and the exit status is unaffected:
211.Bl -tag -width Ds -offset indent
212.It directory Ar subdirectory No unreadable : Ar reason
213A directory below
214.Ar srcdir
215could not be read and is skipped.
216.It directory Ar subdirectory No causes cycle
217A directory below
218.Ar srcdir
219is skipped because it would cause cyclic processing.
220.It Sy mkdirat Ar subdirectory : reason
221A required directory below
222.Ar dstdir
223does not exist and could not be created.
224The corresponding subdirectory below
225.Ar srcdir
226is skipped.
227.El
228.Pp
229Some non-fatal errors cause a single source file to be skipped.
230The iteration is not aborted but continues with the next file,
231and the exit status is unaffected:
232.Bl -tag -width Ds -offset indent
233.It file Ar filename : reason
234The function
235.Xr fts_read 3
236reported a non-fatal error with respect to
237.Ar filename .
238.It file Ar filename : No not a regular file
239For example, it might be a symbolic link or a device file.
240.It Sy open Ar filename No for reading : Ar reason
241A file below
242.Ar srcdir
243could not be read, for example due to permission problems.
244.It Sy openat Ar filename No for writing : Ar reason
245A file below
246.Ar dstdir
247could not be created or truncated, for example due to permission problems.
248.El
249.Pp
250If errors occur, the applicable summary messages appear
251after the end of the iteration:
252.Pp
253.Bl -tag -width Ds -offset indent -compact
254.It skipped Ar number No directories due to errors
255.It skipped Ar number No files due to errors
256.It processing aborted due to fatal error
257.El
258.Pp
259If the
260.Fl v
261flag is specified, the following summary message also appears:
262.Bl -tag -width Ds -offset indent
263.It processed Ar nfiles No files in Ar ndirs No directories
264A file is counted if it could be opened for reading and the
265corresponding output file could be opened for writing;
266this does not necessarily mean that it is a useful manual page.
267A directory is counted if it could be opened for reading and the
268corresponding output directory existed or could be created;
269this does not necessarily mean that any files could be
270processed inside.
271.El
272.Pp
273If the
274.Fl v
275flag is specified twice, the following messages also appear:
276.Bl -tag -width Ds -offset indent
277.It allowing up to Ar number No files in flight
278This is printed at the beginning of the iteration,
279showing the maximum number of files that
280.Nm
281allows to be in flight at any given time.
282.It files in flight: Ar old No \- Ar decrement No = Ar new
283This message is printed when
284.Nm
285learns about
286.Xr mandocd 8
287accepting more than one file at the same time.
288The three numbers printed are the old number of files in flight,
289the amount this number is being reduced, and the resulting
290new number of files in flight.
291.It waiting for Ar number No files in flight
292This message is printed at the end of the iteration, after
293.Nm
294has submitted all files to
295.Xr mandocd 8
296that it intends to.
297THe message informs about the number of files still in flight
298at this point.
299The
300.Nm
301program then waits until
302.Xr mandocd 8
303has accepted them all or until an error occurs.
304.El
305.Sh SEE ALSO
306.Xr mandoc 1 ,
307.Xr mandocd 8
308.Sh HISTORY
309A
310.Nm
311utility first appeared in
312.Fx 1.0 .
313Other, incompatible implementations appeared in
314.Nx 1.0
315and in
316.Sy man-db No 2.2 .
317.Pp
318This version appeared in version 1.14.1 of the
319.Sy mandoc
320toolkit.
321.Sh AUTHORS
322.An -nosplit
323The first
324.Nm
325implementation was a short shell script by
326.An Christoph Robitschko
327in July 1993.
328.Pp
329The
330.Nx
331implementations were written by
332.An J. T. Conklin Aq Mt jtc@netbsd.org
333in 1993,
334.An Christian E. Hopps Aq Mt chopps@netbsd.org
335in 1994,
336and
337.An Dante Profeta Aq Mt dante@netbsd.org
338in 1999; the
339.Sy man-db
340implementation by
341.An Graeme W. Wilford
342in 1994; and the
343.Fx
344implementations by
345.An Wolfram Schneider Aq Mt wosch@freebsd.org
346in 1995 and
347.An John Rochester Aq Mt john@jrochester.org
348in 2002.
349.Pp
350The concept of the present version was designed and implemented by
351.An Michael Stapelberg Aq Mt stapelberg@debian.org
352in 2017.
353Option and argument handling and directory iteration was added by
354.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
355.Sh CAVEATS
356All versions of
357.Nm
358are incompatible with each other because each caters to the needs
359of a specific operating system, for example regarding directory
360structures and file naming conventions.
361.Pp
362This version is more flexible than the others in so far as it does
363not assume any particular directory structure or naming convention.
364That flexibility comes at the price of not being able to change the
365names and relative paths of the source files when reusing them to
366store the formatted files, of not supporting any configuration file
367formats or environment variables, and of being unable to scan for
368and remove junk files in
369.Ar dstdir .
370.Pp
371Currently,
372.Nm
373always reformats each page, even if the formatted version is newer
374than the source version.
375