10da30e9aSPeter Wemm /*-
28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni *
40da30e9aSPeter Wemm * Copyright (c) 1991, 1993
50da30e9aSPeter Wemm * The Regents of the University of California. All rights reserved.
60da30e9aSPeter Wemm *
70da30e9aSPeter Wemm * Redistribution and use in source and binary forms, with or without
80da30e9aSPeter Wemm * modification, are permitted provided that the following conditions
90da30e9aSPeter Wemm * are met:
100da30e9aSPeter Wemm * 1. Redistributions of source code must retain the above copyright
110da30e9aSPeter Wemm * notice, this list of conditions and the following disclaimer.
120da30e9aSPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright
130da30e9aSPeter Wemm * notice, this list of conditions and the following disclaimer in the
140da30e9aSPeter Wemm * documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors
160da30e9aSPeter Wemm * may be used to endorse or promote products derived from this software
170da30e9aSPeter Wemm * without specific prior written permission.
180da30e9aSPeter Wemm *
190da30e9aSPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
200da30e9aSPeter Wemm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
210da30e9aSPeter Wemm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
220da30e9aSPeter Wemm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
230da30e9aSPeter Wemm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
240da30e9aSPeter Wemm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
250da30e9aSPeter Wemm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
260da30e9aSPeter Wemm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
270da30e9aSPeter Wemm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
280da30e9aSPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
290da30e9aSPeter Wemm * SUCH DAMAGE.
300da30e9aSPeter Wemm */
310da30e9aSPeter Wemm
320da30e9aSPeter Wemm #include <sys/types.h>
33c3920857SPhilippe Charnier #include <err.h>
34821df508SXin LI #include <errno.h>
35821df508SXin LI #include <limits.h>
36d10ab05eSTim J. Robbins #include <locale.h>
370da30e9aSPeter Wemm #include <stdio.h>
380da30e9aSPeter Wemm #include <stdlib.h>
39821df508SXin LI #include <string.h>
400da30e9aSPeter Wemm #include <unistd.h>
41d10ab05eSTim J. Robbins #include <wchar.h>
420da30e9aSPeter Wemm
43*95498a5aSFaraz Vahedi #include <capsicum_helpers.h>
44*95498a5aSFaraz Vahedi
450da30e9aSPeter Wemm #define TAB 8
460da30e9aSPeter Wemm
47f1bb2cd2SWarner Losh void check(FILE *);
48498a0a9cSAlfonso Gregory static void usage(void) __dead2;
490da30e9aSPeter Wemm
500da30e9aSPeter Wemm int
main(int argc,char * argv[])516ed42fb9SDavid Malone main(int argc, char *argv[])
520da30e9aSPeter Wemm {
536e47870bSMark Murray u_long column, start, stop;
54d10ab05eSTim J. Robbins int ch, width;
550da30e9aSPeter Wemm char *p;
560da30e9aSPeter Wemm
57d10ab05eSTim J. Robbins setlocale(LC_ALL, "");
58d10ab05eSTim J. Robbins
59*95498a5aSFaraz Vahedi caph_cache_catpages();
60*95498a5aSFaraz Vahedi if (caph_limit_stdio() < 0 || caph_enter() < 0)
61*95498a5aSFaraz Vahedi err(EXIT_FAILURE, "capsicum");
62*95498a5aSFaraz Vahedi
631c8af878SWarner Losh while ((ch = getopt(argc, argv, "")) != -1)
640da30e9aSPeter Wemm switch(ch) {
650da30e9aSPeter Wemm case '?':
660da30e9aSPeter Wemm default:
670da30e9aSPeter Wemm usage();
680da30e9aSPeter Wemm }
690da30e9aSPeter Wemm argc -= optind;
700da30e9aSPeter Wemm argv += optind;
710da30e9aSPeter Wemm
720da30e9aSPeter Wemm start = stop = 0;
730da30e9aSPeter Wemm switch(argc) {
740da30e9aSPeter Wemm case 2:
750da30e9aSPeter Wemm stop = strtol(argv[1], &p, 10);
760da30e9aSPeter Wemm if (stop <= 0 || *p)
77fc26f24bSFaraz Vahedi errx(EXIT_FAILURE, "illegal column -- %s", argv[1]);
780da30e9aSPeter Wemm /* FALLTHROUGH */
790da30e9aSPeter Wemm case 1:
800da30e9aSPeter Wemm start = strtol(argv[0], &p, 10);
810da30e9aSPeter Wemm if (start <= 0 || *p)
82fc26f24bSFaraz Vahedi errx(EXIT_FAILURE, "illegal column -- %s", argv[0]);
830da30e9aSPeter Wemm break;
840da30e9aSPeter Wemm case 0:
850da30e9aSPeter Wemm break;
860da30e9aSPeter Wemm default:
870da30e9aSPeter Wemm usage();
880da30e9aSPeter Wemm }
890da30e9aSPeter Wemm
900da30e9aSPeter Wemm if (stop && start > stop)
91fc26f24bSFaraz Vahedi errx(EXIT_FAILURE, "illegal start and stop columns");
920da30e9aSPeter Wemm
930da30e9aSPeter Wemm for (column = 0;;) {
94d10ab05eSTim J. Robbins switch (ch = getwchar()) {
95d10ab05eSTim J. Robbins case WEOF:
960da30e9aSPeter Wemm check(stdin);
970da30e9aSPeter Wemm break;
980da30e9aSPeter Wemm case '\b':
990da30e9aSPeter Wemm if (column)
1000da30e9aSPeter Wemm --column;
1010da30e9aSPeter Wemm break;
1020da30e9aSPeter Wemm case '\n':
1030da30e9aSPeter Wemm column = 0;
1040da30e9aSPeter Wemm break;
1050da30e9aSPeter Wemm case '\t':
1060da30e9aSPeter Wemm column = (column + TAB) & ~(TAB - 1);
1070da30e9aSPeter Wemm break;
1080da30e9aSPeter Wemm default:
109d10ab05eSTim J. Robbins if ((width = wcwidth(ch)) > 0)
110d10ab05eSTim J. Robbins column += width;
1110da30e9aSPeter Wemm break;
1120da30e9aSPeter Wemm }
1130da30e9aSPeter Wemm
114d7d10053SAlexander Langer if ((!start || column < start || (stop && column > stop)) &&
115d10ab05eSTim J. Robbins putwchar(ch) == WEOF)
1160da30e9aSPeter Wemm check(stdout);
1170da30e9aSPeter Wemm }
1180da30e9aSPeter Wemm }
1190da30e9aSPeter Wemm
1200da30e9aSPeter Wemm void
check(FILE * stream)1216ed42fb9SDavid Malone check(FILE *stream)
1220da30e9aSPeter Wemm {
1230da30e9aSPeter Wemm if (feof(stream))
124fc26f24bSFaraz Vahedi exit(EXIT_SUCCESS);
1250da30e9aSPeter Wemm if (ferror(stream))
126fc26f24bSFaraz Vahedi err(EXIT_FAILURE, "%s", stream == stdin ? "stdin" : "stdout");
1270da30e9aSPeter Wemm }
1280da30e9aSPeter Wemm
1290da30e9aSPeter Wemm void
usage(void)1306ed42fb9SDavid Malone usage(void)
1310da30e9aSPeter Wemm {
1320da30e9aSPeter Wemm (void)fprintf(stderr, "usage: colrm [start [stop]]\n");
133fc26f24bSFaraz Vahedi exit(EXIT_FAILURE);
1340da30e9aSPeter Wemm }
135