/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1991, 1993, 19944* 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 <capsicum_helpers.h>32#include <err.h>33#include <libgen.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>4142void stripsuffix(char *, const char *, size_t);43void usage(void);4445int46main(int argc, char **argv)47{48char *p, *suffix;49size_t suffixlen;50int aflag, ch;5152setlocale(LC_ALL, "");5354if (caph_limit_stdio() < 0 || caph_enter() < 0)55err(1, "capsicum");5657aflag = 0;58suffix = NULL;59suffixlen = 0;6061while ((ch = getopt(argc, argv, "as:")) != -1)62switch(ch) {63case 'a':64aflag = 1;65break;66case 's':67suffix = optarg;68break;69case '?':70default:71usage();72}73argc -= optind;74argv += optind;7576if (argc < 1)77usage();7879if (!*argv[0]) {80printf("\n");81exit(0);82}83if ((p = basename(argv[0])) == NULL)84err(1, "%s", argv[0]);85if ((suffix == NULL && !aflag) && argc == 2) {86suffix = argv[1];87argc--;88}89if (suffix != NULL)90suffixlen = strlen(suffix);91while (argc--) {92if ((p = basename(*argv)) == NULL)93err(1, "%s", argv[0]);94stripsuffix(p, suffix, suffixlen);95argv++;96(void)printf("%s\n", p);97}98exit(0);99}100101void102stripsuffix(char *p, const char *suffix, size_t suffixlen)103{104char *q, *r;105mbstate_t mbs;106size_t n;107108if (suffixlen && (q = strchr(p, '\0') - suffixlen) > p &&109strcmp(suffix, q) == 0) {110/* Ensure that the match occurred on a character boundary. */111memset(&mbs, 0, sizeof(mbs));112for (r = p; r < q; r += n) {113n = mbrlen(r, MB_LEN_MAX, &mbs);114if (n == (size_t)-1 || n == (size_t)-2) {115memset(&mbs, 0, sizeof(mbs));116n = 1;117}118}119/* Chop off the suffix. */120if (q == r)121*q = '\0';122}123}124125void126usage(void)127{128129(void)fprintf(stderr,130"usage: basename string [suffix]\n"131" basename [-a] [-s suffix] string [...]\n");132exit(1);133}134135136