bin/96540: catman does not deal correctly with hard-linked files

Helge Oldach catmanapr06 at
Sun Apr 30 09:10:18 UTC 2006

>Number:         96540
>Category:       bin
>Synopsis:       catman does not deal correctly with hard-linked files
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr 30 09:10:13 GMT 2006
>Originator:     Helge Oldach
>Release:        FreeBSD 5.5-PRERELEASE i386

System: FreeBSD localhost 5.5-PRERELEASE FreeBSD 5.5-PRERELEASE #684: Thu Apr 27 00:38:13 CEST 2006 toor at localhost:/usr/obj/usr/src/sys/HMO i386


(Although this bug has been found on 5.5, it is present in all releases.)

catman(1) does not correctly deal with hard links. This relates to the
situation where the manpage source is a bunch of linked files, which is
the case for example with the builtins to sh(1):

man directory /usr/share/man
  section man1
        format man1/alloc.1.gz -> cat1/alloc.1.gz
        link cat1/bg.1.gz -> cat1/alloc.1.gz
        link cat1/bind.1.gz -> cat1/alloc.1.gz
        link cat1/bindkey.1.gz -> cat1/alloc.1.gz
        link cat1/break.1.gz -> cat1/alloc.1.gz
        link cat1/breaksw.1.gz -> cat1/alloc.1.gz
        link cat1/builtin.1.gz -> cat1/alloc.1.gz
        link cat1/builtins.1.gz -> cat1/alloc.1.gz


The problem occurs if cat1/bg.1.gz already exists. In that case
catman(1) just executes a link(cat1/alloc.1.gz, cat1/bg.1.gz), which
fails with EEXIST. As a result, an old version of cat1/bg.1.gz remains.

As a further complication, some catpages may already exist that are
up to date, but are not hardlinked in the same fashion as the manpage
sources. This might happen if a catman(1) without this fix had created
them already.




Unconditionally remove a catpage link before checking whether it is up
to date. The links will be installed shortly after. Note that this will
take effect only if the first catpage of the linked set of catpages had
been updated already.

--- /usr/src/usr.bin/catman/catman.c.ctm	Thu Jan 13 07:44:17 2005
+++ /usr/src/usr.bin/catman/catman.c	Sun Apr 30 10:49:06 2006
@@ -416,6 +416,14 @@
 	src_dev = test_st.st_dev;
 	src_ino = test_st.st_ino;
+	if ((link_name = find_hashtable(links, src_ino, src_dev)) != NULL) {
+		if (verbose || pretend) {
+			fprintf(stderr, "%sunlink %s\n",
+			    verbose ? "\t" : "", cat);
+		}
+		if (!pretend)
+			unlink(cat);
+	}
 	cat_test = test_path(cat, &cat_mtime);
 	if (cat_test & (TEST_FILE|TEST_READABLE)) {
 		if (!force && cat_mtime >= src_mtime) {


More information about the freebsd-bugs mailing list