1*61d06d6bSBaptiste Daroussin /* $Id: soelim.c,v 1.5 2015/11/07 14:22:29 schwarze Exp $ */ 2*61d06d6bSBaptiste Daroussin /* 3*61d06d6bSBaptiste Daroussin * Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org> 4*61d06d6bSBaptiste Daroussin * All rights reserved. 5*61d06d6bSBaptiste Daroussin * 6*61d06d6bSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7*61d06d6bSBaptiste Daroussin * modification, are permitted provided that the following conditions 8*61d06d6bSBaptiste Daroussin * are met: 9*61d06d6bSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10*61d06d6bSBaptiste Daroussin * notice, this list of conditions and the following disclaimer 11*61d06d6bSBaptiste Daroussin * in this position and unchanged. 12*61d06d6bSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 13*61d06d6bSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 14*61d06d6bSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 15*61d06d6bSBaptiste Daroussin * 16*61d06d6bSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 17*61d06d6bSBaptiste Daroussin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18*61d06d6bSBaptiste Daroussin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19*61d06d6bSBaptiste Daroussin * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 20*61d06d6bSBaptiste Daroussin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21*61d06d6bSBaptiste Daroussin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22*61d06d6bSBaptiste Daroussin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23*61d06d6bSBaptiste Daroussin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*61d06d6bSBaptiste Daroussin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25*61d06d6bSBaptiste Daroussin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*61d06d6bSBaptiste Daroussin */ 27*61d06d6bSBaptiste Daroussin #include "config.h" 28*61d06d6bSBaptiste Daroussin 29*61d06d6bSBaptiste Daroussin #include <sys/types.h> 30*61d06d6bSBaptiste Daroussin 31*61d06d6bSBaptiste Daroussin #include <ctype.h> 32*61d06d6bSBaptiste Daroussin #if HAVE_ERR 33*61d06d6bSBaptiste Daroussin #include <err.h> 34*61d06d6bSBaptiste Daroussin #endif 35*61d06d6bSBaptiste Daroussin #include <limits.h> 36*61d06d6bSBaptiste Daroussin #include <stdio.h> 37*61d06d6bSBaptiste Daroussin #include <stdlib.h> 38*61d06d6bSBaptiste Daroussin #include <string.h> 39*61d06d6bSBaptiste Daroussin #if HAVE_STRINGLIST 40*61d06d6bSBaptiste Daroussin #include <stringlist.h> 41*61d06d6bSBaptiste Daroussin #else 42*61d06d6bSBaptiste Daroussin #include "compat_stringlist.h" 43*61d06d6bSBaptiste Daroussin #endif 44*61d06d6bSBaptiste Daroussin #include <unistd.h> 45*61d06d6bSBaptiste Daroussin 46*61d06d6bSBaptiste Daroussin #define C_OPTION 0x1 47*61d06d6bSBaptiste Daroussin 48*61d06d6bSBaptiste Daroussin static StringList *includes; 49*61d06d6bSBaptiste Daroussin 50*61d06d6bSBaptiste Daroussin static void 51*61d06d6bSBaptiste Daroussin usage(void) 52*61d06d6bSBaptiste Daroussin { 53*61d06d6bSBaptiste Daroussin 54*61d06d6bSBaptiste Daroussin fprintf(stderr, "usage: soelim [-Crtv] [-I dir] [files]\n"); 55*61d06d6bSBaptiste Daroussin 56*61d06d6bSBaptiste Daroussin exit(EXIT_FAILURE); 57*61d06d6bSBaptiste Daroussin } 58*61d06d6bSBaptiste Daroussin 59*61d06d6bSBaptiste Daroussin static FILE * 60*61d06d6bSBaptiste Daroussin soelim_fopen(const char *name) 61*61d06d6bSBaptiste Daroussin { 62*61d06d6bSBaptiste Daroussin FILE *f; 63*61d06d6bSBaptiste Daroussin char path[PATH_MAX]; 64*61d06d6bSBaptiste Daroussin size_t i; 65*61d06d6bSBaptiste Daroussin 66*61d06d6bSBaptiste Daroussin if (strcmp(name, "-") == 0) 67*61d06d6bSBaptiste Daroussin return (stdin); 68*61d06d6bSBaptiste Daroussin 69*61d06d6bSBaptiste Daroussin if ((f = fopen(name, "r")) != NULL) 70*61d06d6bSBaptiste Daroussin return (f); 71*61d06d6bSBaptiste Daroussin 72*61d06d6bSBaptiste Daroussin if (*name == '/') { 73*61d06d6bSBaptiste Daroussin warn("can't open '%s'", name); 74*61d06d6bSBaptiste Daroussin return (NULL); 75*61d06d6bSBaptiste Daroussin } 76*61d06d6bSBaptiste Daroussin 77*61d06d6bSBaptiste Daroussin for (i = 0; i < includes->sl_cur; i++) { 78*61d06d6bSBaptiste Daroussin snprintf(path, sizeof(path), "%s/%s", includes->sl_str[i], 79*61d06d6bSBaptiste Daroussin name); 80*61d06d6bSBaptiste Daroussin if ((f = fopen(path, "r")) != NULL) 81*61d06d6bSBaptiste Daroussin return (f); 82*61d06d6bSBaptiste Daroussin } 83*61d06d6bSBaptiste Daroussin 84*61d06d6bSBaptiste Daroussin warn("can't open '%s'", name); 85*61d06d6bSBaptiste Daroussin 86*61d06d6bSBaptiste Daroussin return (f); 87*61d06d6bSBaptiste Daroussin } 88*61d06d6bSBaptiste Daroussin 89*61d06d6bSBaptiste Daroussin static int 90*61d06d6bSBaptiste Daroussin soelim_file(FILE *f, int flag) 91*61d06d6bSBaptiste Daroussin { 92*61d06d6bSBaptiste Daroussin char *line = NULL; 93*61d06d6bSBaptiste Daroussin char *walk, *cp; 94*61d06d6bSBaptiste Daroussin size_t linecap = 0; 95*61d06d6bSBaptiste Daroussin ssize_t linelen; 96*61d06d6bSBaptiste Daroussin 97*61d06d6bSBaptiste Daroussin if (f == NULL) 98*61d06d6bSBaptiste Daroussin return (1); 99*61d06d6bSBaptiste Daroussin 100*61d06d6bSBaptiste Daroussin while ((linelen = getline(&line, &linecap, f)) > 0) { 101*61d06d6bSBaptiste Daroussin if (strncmp(line, ".so", 3) != 0) { 102*61d06d6bSBaptiste Daroussin printf("%s", line); 103*61d06d6bSBaptiste Daroussin continue; 104*61d06d6bSBaptiste Daroussin } 105*61d06d6bSBaptiste Daroussin 106*61d06d6bSBaptiste Daroussin walk = line + 3; 107*61d06d6bSBaptiste Daroussin if (!isspace(*walk) && ((flag & C_OPTION) == 0)) { 108*61d06d6bSBaptiste Daroussin printf("%s", line); 109*61d06d6bSBaptiste Daroussin continue; 110*61d06d6bSBaptiste Daroussin } 111*61d06d6bSBaptiste Daroussin 112*61d06d6bSBaptiste Daroussin while (isspace(*walk)) 113*61d06d6bSBaptiste Daroussin walk++; 114*61d06d6bSBaptiste Daroussin 115*61d06d6bSBaptiste Daroussin cp = walk; 116*61d06d6bSBaptiste Daroussin while (*cp != '\0' && !isspace(*cp)) 117*61d06d6bSBaptiste Daroussin cp++; 118*61d06d6bSBaptiste Daroussin *cp = 0; 119*61d06d6bSBaptiste Daroussin if (cp < line + linelen) 120*61d06d6bSBaptiste Daroussin cp++; 121*61d06d6bSBaptiste Daroussin 122*61d06d6bSBaptiste Daroussin if (*walk == '\0') { 123*61d06d6bSBaptiste Daroussin printf("%s", line); 124*61d06d6bSBaptiste Daroussin continue; 125*61d06d6bSBaptiste Daroussin } 126*61d06d6bSBaptiste Daroussin if (soelim_file(soelim_fopen(walk), flag) == 1) { 127*61d06d6bSBaptiste Daroussin free(line); 128*61d06d6bSBaptiste Daroussin return (1); 129*61d06d6bSBaptiste Daroussin } 130*61d06d6bSBaptiste Daroussin if (*cp != '\0') 131*61d06d6bSBaptiste Daroussin printf("%s", cp); 132*61d06d6bSBaptiste Daroussin } 133*61d06d6bSBaptiste Daroussin 134*61d06d6bSBaptiste Daroussin free(line); 135*61d06d6bSBaptiste Daroussin fclose(f); 136*61d06d6bSBaptiste Daroussin 137*61d06d6bSBaptiste Daroussin return (0); 138*61d06d6bSBaptiste Daroussin } 139*61d06d6bSBaptiste Daroussin 140*61d06d6bSBaptiste Daroussin int 141*61d06d6bSBaptiste Daroussin main(int argc, char **argv) 142*61d06d6bSBaptiste Daroussin { 143*61d06d6bSBaptiste Daroussin int ch, i; 144*61d06d6bSBaptiste Daroussin int ret = 0; 145*61d06d6bSBaptiste Daroussin int flags = 0; 146*61d06d6bSBaptiste Daroussin 147*61d06d6bSBaptiste Daroussin includes = sl_init(); 148*61d06d6bSBaptiste Daroussin if (includes == NULL) 149*61d06d6bSBaptiste Daroussin err(EXIT_FAILURE, "sl_init()"); 150*61d06d6bSBaptiste Daroussin 151*61d06d6bSBaptiste Daroussin while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { 152*61d06d6bSBaptiste Daroussin switch (ch) { 153*61d06d6bSBaptiste Daroussin case 'C': 154*61d06d6bSBaptiste Daroussin flags |= C_OPTION; 155*61d06d6bSBaptiste Daroussin break; 156*61d06d6bSBaptiste Daroussin case 'r': 157*61d06d6bSBaptiste Daroussin case 'v': 158*61d06d6bSBaptiste Daroussin case 't': 159*61d06d6bSBaptiste Daroussin /* stub compatibility with groff's soelim */ 160*61d06d6bSBaptiste Daroussin break; 161*61d06d6bSBaptiste Daroussin case 'I': 162*61d06d6bSBaptiste Daroussin sl_add(includes, optarg); 163*61d06d6bSBaptiste Daroussin break; 164*61d06d6bSBaptiste Daroussin default: 165*61d06d6bSBaptiste Daroussin sl_free(includes, 0); 166*61d06d6bSBaptiste Daroussin usage(); 167*61d06d6bSBaptiste Daroussin } 168*61d06d6bSBaptiste Daroussin } 169*61d06d6bSBaptiste Daroussin 170*61d06d6bSBaptiste Daroussin argc -= optind; 171*61d06d6bSBaptiste Daroussin argv += optind; 172*61d06d6bSBaptiste Daroussin 173*61d06d6bSBaptiste Daroussin if (argc == 0) 174*61d06d6bSBaptiste Daroussin ret = soelim_file(stdin, flags); 175*61d06d6bSBaptiste Daroussin 176*61d06d6bSBaptiste Daroussin for (i = 0; i < argc; i++) 177*61d06d6bSBaptiste Daroussin ret = soelim_file(soelim_fopen(argv[i]), flags); 178*61d06d6bSBaptiste Daroussin 179*61d06d6bSBaptiste Daroussin sl_free(includes, 0); 180*61d06d6bSBaptiste Daroussin 181*61d06d6bSBaptiste Daroussin return (ret); 182*61d06d6bSBaptiste Daroussin } 183