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(®, 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(®, 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