11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1991, 1993, 1994
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 4. Neither the name of the University nor the names of its contributors
141590Srgrimes *    may be used to endorse or promote products derived from this software
151590Srgrimes *    without specific prior written permission.
161590Srgrimes *
171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271590Srgrimes * SUCH DAMAGE.
281590Srgrimes */
291590Srgrimes
301590Srgrimes#ifndef lint
3141568Sarchiestatic const char copyright[] =
321590Srgrimes"@(#) Copyright (c) 1991, 1993, 1994\n\
331590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
3487258Smarkm#endif
351590Srgrimes
3687628Sdwmalone#if 0
371590Srgrimes#ifndef lint
3887628Sdwmalonestatic char sccsid[] = "@(#)basename.c	8.4 (Berkeley) 5/4/95";
391590Srgrimes#endif /* not lint */
4087628Sdwmalone#endif
411590Srgrimes
4287628Sdwmalone#include <sys/cdefs.h>
4387628Sdwmalone__FBSDID("$FreeBSD$");
4487628Sdwmalone
4565508Sdes#include <err.h>
4665413Sdes#include <libgen.h>
47132187Stjr#include <limits.h>
48132187Stjr#include <locale.h>
491590Srgrimes#include <stdio.h>
5078717Sdd#include <stdlib.h>
5165508Sdes#include <string.h>
5223690Speter#include <unistd.h>
53132187Stjr#include <wchar.h>
541590Srgrimes
55132187Stjrvoid stripsuffix(char *, const char *, size_t);
5692920Simpvoid usage(void);
571590Srgrimes
581590Srgrimesint
59102944Sdwmalonemain(int argc, char **argv)
601590Srgrimes{
61132187Stjr	char *p, *suffix;
6299137Sjmallett	size_t suffixlen;
6399137Sjmallett	int aflag, ch;
641590Srgrimes
65132187Stjr	setlocale(LC_ALL, "");
66132187Stjr
6799137Sjmallett	aflag = 0;
6899137Sjmallett	suffix = NULL;
6999137Sjmallett	suffixlen = 0;
7099137Sjmallett
7199137Sjmallett	while ((ch = getopt(argc, argv, "as:")) != -1)
721590Srgrimes		switch(ch) {
7399137Sjmallett		case 'a':
7499137Sjmallett			aflag = 1;
7599137Sjmallett			break;
7699137Sjmallett		case 's':
7799137Sjmallett			suffix = optarg;
7899137Sjmallett			break;
791590Srgrimes		case '?':
801590Srgrimes		default:
811590Srgrimes			usage();
821590Srgrimes		}
831590Srgrimes	argc -= optind;
841590Srgrimes	argv += optind;
851590Srgrimes
8699137Sjmallett	if (argc < 1)
871590Srgrimes		usage();
881590Srgrimes
8967024Sdes	if (!*argv[0]) {
9067024Sdes		printf("\n");
9167024Sdes		exit(0);
9267024Sdes	}
9365508Sdes	if ((p = basename(argv[0])) == NULL)
9465508Sdes		err(1, "%s", argv[0]);
9599137Sjmallett	if ((suffix == NULL && !aflag) && argc == 2) {
9699137Sjmallett		suffix = argv[1];
9799137Sjmallett		argc--;
9899137Sjmallett	}
9999137Sjmallett	if (suffix != NULL)
10099137Sjmallett		suffixlen = strlen(suffix);
10199137Sjmallett	while (argc--) {
10299137Sjmallett		if ((p = basename(*argv)) == NULL)
10399137Sjmallett			err(1, "%s", argv[0]);
104132187Stjr		stripsuffix(p, suffix, suffixlen);
10599137Sjmallett		argv++;
10699137Sjmallett		(void)printf("%s\n", p);
10799137Sjmallett	}
1081590Srgrimes	exit(0);
1091590Srgrimes}
1101590Srgrimes
1111590Srgrimesvoid
112132187Stjrstripsuffix(char *p, const char *suffix, size_t suffixlen)
113132187Stjr{
114132187Stjr	char *q, *r;
115132187Stjr	mbstate_t mbs;
116132187Stjr	size_t n;
117132187Stjr
118132187Stjr	if (suffixlen && (q = strchr(p, '\0') - suffixlen) > p &&
119132187Stjr	    strcmp(suffix, q) == 0) {
120132187Stjr		/* Ensure that the match occurred on a character boundary. */
121132187Stjr		memset(&mbs, 0, sizeof(mbs));
122132187Stjr		for (r = p; r < q; r += n) {
123132187Stjr			n = mbrlen(r, MB_LEN_MAX, &mbs);
124132187Stjr			if (n == (size_t)-1 || n == (size_t)-2) {
125132187Stjr				memset(&mbs, 0, sizeof(mbs));
126132187Stjr				n = 1;
127132187Stjr			}
128132187Stjr		}
129132187Stjr		/* Chop off the suffix. */
130132187Stjr		if (q == r)
131132187Stjr			*q = '\0';
132132187Stjr	}
133132187Stjr}
134132187Stjr
135132187Stjrvoid
136102944Sdwmaloneusage(void)
1371590Srgrimes{
1381590Srgrimes
13999137Sjmallett	(void)fprintf(stderr,
14099137Sjmallett"usage: basename string [suffix]\n"
14199137Sjmallett"       basename [-a] [-s suffix] string [...]\n");
1421590Srgrimes	exit(1);
1431590Srgrimes}
144