basename.c revision 132187
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 * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3541568Sarchiestatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1991, 1993, 1994\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 3887258Smarkm#endif 391590Srgrimes 4087628Sdwmalone#if 0 411590Srgrimes#ifndef lint 4287628Sdwmalonestatic char sccsid[] = "@(#)basename.c 8.4 (Berkeley) 5/4/95"; 431590Srgrimes#endif /* not lint */ 4487628Sdwmalone#endif 451590Srgrimes 4687628Sdwmalone#include <sys/cdefs.h> 4787628Sdwmalone__FBSDID("$FreeBSD: head/usr.bin/basename/basename.c 132187 2004-07-15 06:15:10Z tjr $"); 4887628Sdwmalone 4965508Sdes#include <err.h> 5065413Sdes#include <libgen.h> 51132187Stjr#include <limits.h> 52132187Stjr#include <locale.h> 531590Srgrimes#include <stdio.h> 5478717Sdd#include <stdlib.h> 5565508Sdes#include <string.h> 5623690Speter#include <unistd.h> 57132187Stjr#include <wchar.h> 581590Srgrimes 59132187Stjrvoid stripsuffix(char *, const char *, size_t); 6092920Simpvoid usage(void); 611590Srgrimes 621590Srgrimesint 63102944Sdwmalonemain(int argc, char **argv) 641590Srgrimes{ 65132187Stjr char *p, *suffix; 6699137Sjmallett size_t suffixlen; 6799137Sjmallett int aflag, ch; 681590Srgrimes 69132187Stjr setlocale(LC_ALL, ""); 70132187Stjr 7199137Sjmallett aflag = 0; 7299137Sjmallett suffix = NULL; 7399137Sjmallett suffixlen = 0; 7499137Sjmallett 7599137Sjmallett while ((ch = getopt(argc, argv, "as:")) != -1) 761590Srgrimes switch(ch) { 7799137Sjmallett case 'a': 7899137Sjmallett aflag = 1; 7999137Sjmallett break; 8099137Sjmallett case 's': 8199137Sjmallett suffix = optarg; 8299137Sjmallett break; 831590Srgrimes case '?': 841590Srgrimes default: 851590Srgrimes usage(); 861590Srgrimes } 871590Srgrimes argc -= optind; 881590Srgrimes argv += optind; 891590Srgrimes 9099137Sjmallett if (argc < 1) 911590Srgrimes usage(); 921590Srgrimes 9367024Sdes if (!*argv[0]) { 9467024Sdes printf("\n"); 9567024Sdes exit(0); 9667024Sdes } 9765508Sdes if ((p = basename(argv[0])) == NULL) 9865508Sdes err(1, "%s", argv[0]); 9999137Sjmallett if ((suffix == NULL && !aflag) && argc == 2) { 10099137Sjmallett suffix = argv[1]; 10199137Sjmallett argc--; 10299137Sjmallett } 10399137Sjmallett if (suffix != NULL) 10499137Sjmallett suffixlen = strlen(suffix); 10599137Sjmallett while (argc--) { 10699137Sjmallett if ((p = basename(*argv)) == NULL) 10799137Sjmallett err(1, "%s", argv[0]); 108132187Stjr stripsuffix(p, suffix, suffixlen); 10999137Sjmallett argv++; 11099137Sjmallett (void)printf("%s\n", p); 11199137Sjmallett } 1121590Srgrimes exit(0); 1131590Srgrimes} 1141590Srgrimes 1151590Srgrimesvoid 116132187Stjrstripsuffix(char *p, const char *suffix, size_t suffixlen) 117132187Stjr{ 118132187Stjr char *q, *r; 119132187Stjr mbstate_t mbs; 120132187Stjr size_t n; 121132187Stjr 122132187Stjr if (suffixlen && (q = strchr(p, '\0') - suffixlen) > p && 123132187Stjr strcmp(suffix, q) == 0) { 124132187Stjr /* Ensure that the match occurred on a character boundary. */ 125132187Stjr memset(&mbs, 0, sizeof(mbs)); 126132187Stjr for (r = p; r < q; r += n) { 127132187Stjr n = mbrlen(r, MB_LEN_MAX, &mbs); 128132187Stjr if (n == (size_t)-1 || n == (size_t)-2) { 129132187Stjr memset(&mbs, 0, sizeof(mbs)); 130132187Stjr n = 1; 131132187Stjr } 132132187Stjr } 133132187Stjr /* Chop off the suffix. */ 134132187Stjr if (q == r) 135132187Stjr *q = '\0'; 136132187Stjr } 137132187Stjr} 138132187Stjr 139132187Stjrvoid 140102944Sdwmaloneusage(void) 1411590Srgrimes{ 1421590Srgrimes 14399137Sjmallett (void)fprintf(stderr, 14499137Sjmallett"usage: basename string [suffix]\n" 14599137Sjmallett" basename [-a] [-s suffix] string [...]\n"); 1461590Srgrimes exit(1); 1471590Srgrimes} 148