/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1991, 19934* The Regents of the University of California. All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. Neither the name of the University nor the names of its contributors15* may be used to endorse or promote products derived from this software16* without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include <sys/types.h>32#include <err.h>33#include <errno.h>34#include <limits.h>35#include <locale.h>36#include <stdio.h>37#include <stdlib.h>38#include <string.h>39#include <unistd.h>40#include <wchar.h>4142#include <capsicum_helpers.h>4344#define TAB 84546void check(FILE *);47static void usage(void) __dead2;4849int50main(int argc, char *argv[])51{52u_long column, start, stop;53int ch, width;54char *p;5556setlocale(LC_ALL, "");5758caph_cache_catpages();59if (caph_limit_stdio() < 0 || caph_enter() < 0)60err(EXIT_FAILURE, "capsicum");6162while ((ch = getopt(argc, argv, "")) != -1)63switch(ch) {64case '?':65default:66usage();67}68argc -= optind;69argv += optind;7071start = stop = 0;72switch(argc) {73case 2:74stop = strtol(argv[1], &p, 10);75if (stop <= 0 || *p)76errx(EXIT_FAILURE, "illegal column -- %s", argv[1]);77/* FALLTHROUGH */78case 1:79start = strtol(argv[0], &p, 10);80if (start <= 0 || *p)81errx(EXIT_FAILURE, "illegal column -- %s", argv[0]);82break;83case 0:84break;85default:86usage();87}8889if (stop && start > stop)90errx(EXIT_FAILURE, "illegal start and stop columns");9192for (column = 0;;) {93switch (ch = getwchar()) {94case WEOF:95check(stdin);96break;97case '\b':98if (column)99--column;100break;101case '\n':102column = 0;103break;104case '\t':105column = (column + TAB) & ~(TAB - 1);106break;107default:108if ((width = wcwidth(ch)) > 0)109column += width;110break;111}112113if ((!start || column < start || (stop && column > stop)) &&114putwchar(ch) == WEOF)115check(stdout);116}117}118119void120check(FILE *stream)121{122if (feof(stream))123exit(EXIT_SUCCESS);124if (ferror(stream))125err(EXIT_FAILURE, "%s", stream == stdin ? "stdin" : "stdout");126}127128void129usage(void)130{131(void)fprintf(stderr, "usage: colrm [start [stop]]\n");132exit(EXIT_FAILURE);133}134135136