xref: /titanic_44/usr/src/cmd/basename/basename.c (revision 55381082fdea0647bb5d44ceeed7d5af386f30d2)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*55381082Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <locale.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <string.h>
33*55381082Smuffin #ifndef	XPG4
34*55381082Smuffin #include <unistd.h>
35*55381082Smuffin #include <regex.h>
36*55381082Smuffin #include <libintl.h>
37*55381082Smuffin #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)407c478bd9Sstevel@tonic-gate main(int argc, char **argv)
417c478bd9Sstevel@tonic-gate {
427c478bd9Sstevel@tonic-gate 	char	*p;
437c478bd9Sstevel@tonic-gate 	char	*string;
447c478bd9Sstevel@tonic-gate 	char	*suffix;
45*55381082Smuffin #ifndef	XPG4
46*55381082Smuffin 	int	r;
47*55381082Smuffin 	char	suf_buf[256];
48*55381082Smuffin 	char	*suf_pat;
49*55381082Smuffin 	size_t	suf_len;
50*55381082Smuffin 	regex_t	reg;
51*55381082Smuffin 	regmatch_t	pmatch[2];
52*55381082Smuffin #endif
537c478bd9Sstevel@tonic-gate 
54*55381082Smuffin 	/*
55*55381082Smuffin 	 * For better performance, defer the setlocale()/textdomain()
56*55381082Smuffin 	 * calls until they get really required.
57*55381082Smuffin 	 */
587c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
597c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
607c478bd9Sstevel@tonic-gate #endif
61*55381082Smuffin 	if (argc == 1) {
62*55381082Smuffin 		(void) puts(".");
63*55381082Smuffin 		return (0);
64*55381082Smuffin 	}
657c478bd9Sstevel@tonic-gate 
66*55381082Smuffin #ifdef	XPG4
677c478bd9Sstevel@tonic-gate 	if (strcmp(argv[1], "--") == 0) {
687c478bd9Sstevel@tonic-gate 		argv++;
697c478bd9Sstevel@tonic-gate 		argc--;
70*55381082Smuffin 		if (argc == 1) {
71*55381082Smuffin 			(void) puts(".");
72*55381082Smuffin 			return (0);
737c478bd9Sstevel@tonic-gate 		}
74*55381082Smuffin 	}
75*55381082Smuffin #endif
76*55381082Smuffin 	if (argc > 3) {
77*55381082Smuffin 		(void) setlocale(LC_ALL, "");
78*55381082Smuffin 		(void) textdomain(TEXT_DOMAIN);
79*55381082Smuffin 		(void) fputs(gettext("Usage: basename string [ suffix ]\n"),
80*55381082Smuffin 		    stderr);
81*55381082Smuffin 		return (1);
82*55381082Smuffin 	}
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	string = argv[1];
857c478bd9Sstevel@tonic-gate 	suffix = (argc == 2) ? NULL : argv[2];
867c478bd9Sstevel@tonic-gate 
87*55381082Smuffin 	if (*string == '\0') {
88*55381082Smuffin 		(void) puts(".");
89*55381082Smuffin 		return (0);
90*55381082Smuffin 	}
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	/* remove trailing slashes */
937c478bd9Sstevel@tonic-gate 	p = string + strlen(string) - 1;
94*55381082Smuffin 	while (p >= string && *p == '/')
957c478bd9Sstevel@tonic-gate 		*p-- = '\0';
967c478bd9Sstevel@tonic-gate 
97*55381082Smuffin 	if (*string == '\0') {
98*55381082Smuffin 		(void) puts("/");
99*55381082Smuffin 		return (0);
100*55381082Smuffin 	}
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	/* skip to one past last slash */
1037c478bd9Sstevel@tonic-gate 	if ((p = strrchr(string, '/')) != NULL)
1047c478bd9Sstevel@tonic-gate 		string = p + 1;
1057c478bd9Sstevel@tonic-gate 
106*55381082Smuffin 	if (suffix == NULL) {
107*55381082Smuffin 		(void) puts(string);
108*55381082Smuffin 		return (0);
109*55381082Smuffin 	}
110*55381082Smuffin 
111*55381082Smuffin #ifdef	XPG4
1127c478bd9Sstevel@tonic-gate 	/*
1137c478bd9Sstevel@tonic-gate 	 * if a suffix is present and is not the same as the remaining
1147c478bd9Sstevel@tonic-gate 	 * string and is identical to the last characters in the remaining
1157c478bd9Sstevel@tonic-gate 	 * string, remove those characters from the string.
1167c478bd9Sstevel@tonic-gate 	 */
117*55381082Smuffin 	if (strcmp(string, suffix) != 0) {
1187c478bd9Sstevel@tonic-gate 		p = string + strlen(string) - strlen(suffix);
119*55381082Smuffin 		if (strcmp(p, suffix) == 0)
1207c478bd9Sstevel@tonic-gate 			*p = '\0';
1217c478bd9Sstevel@tonic-gate 	}
122*55381082Smuffin 	(void) puts(string);
123*55381082Smuffin 	return (0);
124*55381082Smuffin #else
125*55381082Smuffin 	(void) setlocale(LC_ALL, "");
126*55381082Smuffin 	(void) textdomain(TEXT_DOMAIN);
1277c478bd9Sstevel@tonic-gate 
128*55381082Smuffin 	suf_len = 6 + strlen(suffix) + 1 + 1; /* \(.*\)suffix$ */
129*55381082Smuffin 	if (suf_len > sizeof (suf_buf)) {
130*55381082Smuffin 		suf_pat = malloc(suf_len);
131*55381082Smuffin 		if (suf_pat == NULL) {
132*55381082Smuffin 			(void) fputs("malloc failed\n", stderr);
133*55381082Smuffin 			return (1);
134*55381082Smuffin 		}
135*55381082Smuffin 	} else {
136*55381082Smuffin 		suf_pat = suf_buf;
137*55381082Smuffin 	}
138*55381082Smuffin 	(void) strcpy(suf_pat, "\\(.*\\)");
139*55381082Smuffin 	(void) strcpy(suf_pat + 6, suffix);
140*55381082Smuffin 	*(suf_pat + suf_len - 1 - 1) = '$';
141*55381082Smuffin 	*(suf_pat + suf_len - 1) = '\0';
142*55381082Smuffin 
143*55381082Smuffin 	r = regcomp(&reg, suf_pat, 0);
144*55381082Smuffin 	if (r != 0) {
145*55381082Smuffin 		(void) fprintf(stderr,
146*55381082Smuffin 		    "Internal error: regcomp failed for \"%s\"\n",
147*55381082Smuffin 		    suf_pat);
148*55381082Smuffin 		return (1);
149*55381082Smuffin 	}
150*55381082Smuffin 	r = regexec(&reg, string, 2, pmatch, 0);
151*55381082Smuffin 	if (r == 0) {
152*55381082Smuffin 		if (pmatch[0].rm_so == (regoff_t)-1 ||
153*55381082Smuffin 		    pmatch[1].rm_so == (regoff_t)-1 ||
154*55381082Smuffin 		    pmatch[1].rm_so != 0) {
155*55381082Smuffin 			(void) fprintf(stderr, "Internal error: regexec did "
156*55381082Smuffin 			    "not set sub-expression for:\n");
157*55381082Smuffin 			(void) fprintf(stderr, "path: \"%s\"\n", string);
158*55381082Smuffin 			(void) fprintf(stderr, "pattern: \"%s\"", suf_pat);
159*55381082Smuffin 			return (1);
160*55381082Smuffin 		}
161*55381082Smuffin 		if (pmatch[1].rm_so == pmatch[1].rm_eo) {
162*55381082Smuffin 			/* a null string matched */
163*55381082Smuffin 			(void) printf("%s\n", string);
1647c478bd9Sstevel@tonic-gate 			return (0);
1657c478bd9Sstevel@tonic-gate 		}
166*55381082Smuffin 		string[pmatch[1].rm_eo] = '\0';
1677c478bd9Sstevel@tonic-gate 	}
168*55381082Smuffin 	(void) puts(string);
169*55381082Smuffin 	return (0);
170*55381082Smuffin #endif
1717c478bd9Sstevel@tonic-gate }
172