mlinks.c revision 1.1
1/* $OpenBSD: mlinks.c,v 1.1 2016/11/04 19:57:27 schwarze Exp $ */ 2/* 3 * Copyright (c) 2016 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 * Some operating systems need MLINKS for pages with more than one name. 18 * Extract these in a format suitable for portable LibreSSL. 19 */ 20#include <err.h> 21#include <regex.h> 22#include <stdint.h> 23#include <stdio.h> 24#include <string.h> 25 26#include "dbm_map.h" 27#include "dbm.h" 28 29int 30main(int argc, char *argv[]) 31{ 32 const int32_t *pp; /* Page record in the pages table. */ 33 const char *np; /* Names of the page. */ 34 const char *fp; /* Primary filename of the page. */ 35 const char *ep; /* Filname extension including the dot. */ 36 size_t nlen; 37 int32_t i, npages; 38 39 if (argc != 2) 40 errx(1, "usage: mlinks filename"); 41 42 if (dbm_open(argv[1]) == -1) 43 err(1, "%s", argv[1]); 44 45 pp = dbm_getint(4); 46 npages = be32toh(*pp++); 47 if (npages <= 0) 48 errx(1, "database empty or corrupt: %d pages", npages); 49 50 for (i = 0; i < npages; i++, pp += 5) { 51 np = dbm_get(pp[0]); 52 if (np == NULL) 53 errx(1, "database corrupt: bad name pointer"); 54 55 /* Skip files with just one name. */ 56 if (strchr(np, '\0')[1] == '\0') 57 continue; 58 59 fp = dbm_get(pp[4]); 60 if (fp == NULL) 61 errx(1, "database corrupt: bad file pointer"); 62 63 /* Skip the file type byte. */ 64 fp++; 65 66 /* Skip directory parts of filenames. */ 67 ep = strrchr(fp, '/'); 68 if (ep != NULL) 69 fp = ep + 1; 70 71 ep = strrchr(fp, '.'); 72 if (ep == NULL) 73 errx(1, "no filename extension: %s", fp); 74 75 while (*np != '\0') { 76 77 /* Skip the name type byte. */ 78 np++; 79 80 /* Skip the primary filename. */ 81 nlen = strlen(np); 82 if (strncmp(fp, np, nlen) == 0) { 83 np = strchr(np, '\0') + 1; 84 continue; 85 } 86 87 /* Describe the desired mlink. */ 88 printf("%s,", fp); 89 while (*np != '\0') 90 putchar(*np++); 91 np++; 92 puts(ep); 93 } 94 } 95 dbm_close(); 96 return 0; 97} 98