1*4e948f3eSschwarze /* $OpenBSD: mlinks.c,v 1.3 2016/11/05 16:43:50 schwarze Exp $ */
2fc61954aSschwarze /*
3fc61954aSschwarze * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4fc61954aSschwarze *
5fc61954aSschwarze * Permission to use, copy, modify, and distribute this software for any
6fc61954aSschwarze * purpose with or without fee is hereby granted, provided that the above
7fc61954aSschwarze * copyright notice and this permission notice appear in all copies.
8fc61954aSschwarze *
9fc61954aSschwarze * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10fc61954aSschwarze * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11fc61954aSschwarze * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12fc61954aSschwarze * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13fc61954aSschwarze * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14fc61954aSschwarze * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15fc61954aSschwarze * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16fc61954aSschwarze *
17fc61954aSschwarze * Some operating systems need MLINKS for pages with more than one name.
18fc61954aSschwarze * Extract these in a format suitable for portable LibreSSL.
19fc61954aSschwarze */
20fc61954aSschwarze #include <err.h>
21fc61954aSschwarze #include <regex.h>
22fc61954aSschwarze #include <stdint.h>
23fc61954aSschwarze #include <stdio.h>
24fc61954aSschwarze #include <string.h>
25fc61954aSschwarze
26fc61954aSschwarze #include "dbm_map.h"
27fc61954aSschwarze #include "dbm.h"
28fc61954aSschwarze
29fc61954aSschwarze int
main(int argc,char * argv[])30fc61954aSschwarze main(int argc, char *argv[])
31fc61954aSschwarze {
32fc61954aSschwarze const int32_t *pp; /* Page record in the pages table. */
33fc61954aSschwarze const char *np; /* Names of the page. */
34fc61954aSschwarze const char *fp; /* Primary filename of the page. */
35fc61954aSschwarze const char *ep; /* Filname extension including the dot. */
364b884190Sschwarze size_t flen, nlen;
37fc61954aSschwarze int32_t i, npages;
38fc61954aSschwarze
39fc61954aSschwarze if (argc != 2)
40fc61954aSschwarze errx(1, "usage: mlinks filename");
41fc61954aSschwarze
42fc61954aSschwarze if (dbm_open(argv[1]) == -1)
43fc61954aSschwarze err(1, "%s", argv[1]);
44fc61954aSschwarze
45fc61954aSschwarze pp = dbm_getint(4);
46fc61954aSschwarze npages = be32toh(*pp++);
47fc61954aSschwarze if (npages <= 0)
48fc61954aSschwarze errx(1, "database empty or corrupt: %d pages", npages);
49fc61954aSschwarze
50fc61954aSschwarze for (i = 0; i < npages; i++, pp += 5) {
51fc61954aSschwarze np = dbm_get(pp[0]);
52fc61954aSschwarze if (np == NULL)
53fc61954aSschwarze errx(1, "database corrupt: bad name pointer");
54fc61954aSschwarze
55fc61954aSschwarze /* Skip files with just one name. */
56fc61954aSschwarze if (strchr(np, '\0')[1] == '\0')
57fc61954aSschwarze continue;
58fc61954aSschwarze
59fc61954aSschwarze fp = dbm_get(pp[4]);
60fc61954aSschwarze if (fp == NULL)
61fc61954aSschwarze errx(1, "database corrupt: bad file pointer");
62fc61954aSschwarze
63fc61954aSschwarze /* Skip the file type byte. */
64fc61954aSschwarze fp++;
65fc61954aSschwarze
66fc61954aSschwarze /* Skip directory parts of filenames. */
67fc61954aSschwarze ep = strrchr(fp, '/');
68fc61954aSschwarze if (ep != NULL)
69fc61954aSschwarze fp = ep + 1;
70fc61954aSschwarze
71fc61954aSschwarze ep = strrchr(fp, '.');
72fc61954aSschwarze if (ep == NULL)
73fc61954aSschwarze errx(1, "no filename extension: %s", fp);
74*4e948f3eSschwarze flen = ep - fp;
75fc61954aSschwarze
76fc61954aSschwarze while (*np != '\0') {
77fc61954aSschwarze
78fc61954aSschwarze /* Skip the name type byte. */
79fc61954aSschwarze np++;
80fc61954aSschwarze
81fc61954aSschwarze /* Skip the primary filename. */
82fc61954aSschwarze nlen = strlen(np);
834b884190Sschwarze if (nlen == flen && strncmp(fp, np, nlen) == 0) {
84fc61954aSschwarze np = strchr(np, '\0') + 1;
85fc61954aSschwarze continue;
86fc61954aSschwarze }
87fc61954aSschwarze
88fc61954aSschwarze /* Describe the desired mlink. */
89fc61954aSschwarze printf("%s,", fp);
90fc61954aSschwarze while (*np != '\0')
91fc61954aSschwarze putchar(*np++);
92fc61954aSschwarze np++;
93fc61954aSschwarze puts(ep);
94fc61954aSschwarze }
95fc61954aSschwarze }
96fc61954aSschwarze dbm_close();
97fc61954aSschwarze return 0;
98fc61954aSschwarze }
99