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 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