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 #include <locale.h>
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
31*55381082Smuffin #ifndef XPG4
32*55381082Smuffin #include <unistd.h>
33*55381082Smuffin #include <regex.h>
34*55381082Smuffin #include <libintl.h>
35*55381082Smuffin #endif
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)387c478bd9Sstevel@tonic-gate main(int argc, char **argv)
397c478bd9Sstevel@tonic-gate {
407c478bd9Sstevel@tonic-gate char *p;
417c478bd9Sstevel@tonic-gate char *string;
427c478bd9Sstevel@tonic-gate char *suffix;
43*55381082Smuffin #ifndef XPG4
44*55381082Smuffin int r;
45*55381082Smuffin char suf_buf[256];
46*55381082Smuffin char *suf_pat;
47*55381082Smuffin size_t suf_len;
48*55381082Smuffin regex_t reg;
49*55381082Smuffin regmatch_t pmatch[2];
50*55381082Smuffin #endif
517c478bd9Sstevel@tonic-gate
52*55381082Smuffin /*
53*55381082Smuffin * For better performance, defer the setlocale()/textdomain()
54*55381082Smuffin * calls until they get really required.
55*55381082Smuffin */
567c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
577c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
587c478bd9Sstevel@tonic-gate #endif
59*55381082Smuffin if (argc == 1) {
60*55381082Smuffin (void) puts(".");
61*55381082Smuffin return (0);
62*55381082Smuffin }
637c478bd9Sstevel@tonic-gate
64*55381082Smuffin #ifdef XPG4
657c478bd9Sstevel@tonic-gate if (strcmp(argv[1], "--") == 0) {
667c478bd9Sstevel@tonic-gate argv++;
677c478bd9Sstevel@tonic-gate argc--;
68*55381082Smuffin if (argc == 1) {
69*55381082Smuffin (void) puts(".");
70*55381082Smuffin return (0);
71*55381082Smuffin }
72*55381082Smuffin }
73*55381082Smuffin #endif
74*55381082Smuffin if (argc > 3) {
75*55381082Smuffin (void) setlocale(LC_ALL, "");
76*55381082Smuffin (void) textdomain(TEXT_DOMAIN);
77*55381082Smuffin (void) fputs(gettext("Usage: basename string [ suffix ]\n"),
78*55381082Smuffin stderr);
79*55381082Smuffin return (1);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate string = argv[1];
837c478bd9Sstevel@tonic-gate suffix = (argc == 2) ? NULL : argv[2];
847c478bd9Sstevel@tonic-gate
85*55381082Smuffin if (*string == '\0') {
86*55381082Smuffin (void) puts(".");
87*55381082Smuffin return (0);
88*55381082Smuffin }
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate /* remove trailing slashes */
91*55381082Smuffin p = string + strlen(string) - 1;
92*55381082Smuffin while (p >= string && *p == '/')
937c478bd9Sstevel@tonic-gate *p-- = '\0';
947c478bd9Sstevel@tonic-gate
95*55381082Smuffin if (*string == '\0') {
96*55381082Smuffin (void) puts("/");
97*55381082Smuffin return (0);
98*55381082Smuffin }
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate /* skip to one past last slash */
1017c478bd9Sstevel@tonic-gate if ((p = strrchr(string, '/')) != NULL)
1027c478bd9Sstevel@tonic-gate string = p + 1;
1037c478bd9Sstevel@tonic-gate
104*55381082Smuffin if (suffix == NULL) {
105*55381082Smuffin (void) puts(string);
106*55381082Smuffin return (0);
107*55381082Smuffin }
108*55381082Smuffin
109*55381082Smuffin #ifdef XPG4
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate * if a suffix is present and is not the same as the remaining
1127c478bd9Sstevel@tonic-gate * string and is identical to the last characters in the remaining
1137c478bd9Sstevel@tonic-gate * string, remove those characters from the string.
1147c478bd9Sstevel@tonic-gate */
115*55381082Smuffin if (strcmp(string, suffix) != 0) {
116*55381082Smuffin p = string + strlen(string) - strlen(suffix);
117*55381082Smuffin if (strcmp(p, suffix) == 0)
118*55381082Smuffin *p = '\0';
119*55381082Smuffin }
120*55381082Smuffin (void) puts(string);
1217c478bd9Sstevel@tonic-gate return (0);
122*55381082Smuffin #else
123*55381082Smuffin (void) setlocale(LC_ALL, "");
124*55381082Smuffin (void) textdomain(TEXT_DOMAIN);
1257c478bd9Sstevel@tonic-gate
126*55381082Smuffin suf_len = 6 + strlen(suffix) + 1 + 1; /* \(.*\)suffix$ */
127*55381082Smuffin if (suf_len > sizeof (suf_buf)) {
128*55381082Smuffin suf_pat = malloc(suf_len);
129*55381082Smuffin if (suf_pat == NULL) {
130*55381082Smuffin (void) fputs("malloc failed\n", stderr);
131*55381082Smuffin return (1);
132*55381082Smuffin }
133*55381082Smuffin } else {
134*55381082Smuffin suf_pat = suf_buf;
135*55381082Smuffin }
136*55381082Smuffin (void) strcpy(suf_pat, "\\(.*\\)");
137*55381082Smuffin (void) strcpy(suf_pat + 6, suffix);
138*55381082Smuffin *(suf_pat + suf_len - 1 - 1) = '$';
139*55381082Smuffin *(suf_pat + suf_len - 1) = '\0';
140*55381082Smuffin
141*55381082Smuffin r = regcomp(®, suf_pat, 0);
142*55381082Smuffin if (r != 0) {
143*55381082Smuffin (void) fprintf(stderr,
144*55381082Smuffin "Internal error: regcomp failed for \"%s\"\n",
145*55381082Smuffin suf_pat);
146*55381082Smuffin return (1);
147*55381082Smuffin }
148*55381082Smuffin r = regexec(®, string, 2, pmatch, 0);
149*55381082Smuffin if (r == 0) {
150*55381082Smuffin if (pmatch[0].rm_so == (regoff_t)-1 ||
151*55381082Smuffin pmatch[1].rm_so == (regoff_t)-1 ||
152*55381082Smuffin pmatch[1].rm_so != 0) {
153*55381082Smuffin (void) fprintf(stderr, "Internal error: regexec did "
154*55381082Smuffin "not set sub-expression for:\n");
155*55381082Smuffin (void) fprintf(stderr, "path: \"%s\"\n", string);
156*55381082Smuffin (void) fprintf(stderr, "pattern: \"%s\"", suf_pat);
157*55381082Smuffin return (1);
158*55381082Smuffin }
159*55381082Smuffin if (pmatch[1].rm_so == pmatch[1].rm_eo) {
160*55381082Smuffin /* a null string matched */
161*55381082Smuffin (void) printf("%s\n", string);
162*55381082Smuffin return (0);
163*55381082Smuffin }
164*55381082Smuffin string[pmatch[1].rm_eo] = '\0';
165*55381082Smuffin }
166*55381082Smuffin (void) puts(string);
167*55381082Smuffin return (0);
168*55381082Smuffin #endif
1697c478bd9Sstevel@tonic-gate }
170