1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1996, by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * MKS Library -- basename -- produce base name of a file name 31 * NOTE: not standard SVID routine. 32 * 33 * Copyright 1985, 1995 by Mortice Kern Systems Inc. All rights reserved. 34 * 35 * james Partanen, June '95 36 * 37 */ 38 #ifdef M_RCSID 39 #ifndef lint 40 static char rcsID[] = "$Header: /rd/src/libc/gen/rcs/base.c 1.26 1995/08/02 17:32:36 rodney Exp $"; 41 #endif 42 #endif 43 44 #include <string.h> 45 46 #define DIRNAME 0 47 #define BASENAME 1 48 49 #define M_FSDELIM(c) ((c)=='/') 50 #define M_DRDELIM(c) (0) 51 52 static char curdir[] = "."; 53 54 /*f 55 * Since the goal is essentially common: find the last occurring 56 * M_FSDELIM, and since most of the degenerate cases end up with the 57 * same result, let's do most of the work in one function. 58 * - check degenerate arg forms 59 * - deal with a possible drive specifier 60 * - deal with degenerate paths 61 * - find last non-trailing M_FSDELIM 62 * - deal with degenerate dirname 63 * - deal with general case, returning prefix or suffix based on type 64 */ 65 static char * 66 basedir(char *arg, int type) 67 { 68 register char *cp, *path; 69 70 if (arg==(char *)0 || *arg=='\0' || 71 (*arg=='.' && (arg[1]=='\0' || 72 (type==DIRNAME && arg[1]=='.' && arg[2]=='\0')))) 73 74 return curdir; /* arg NULL, empty, ".", or ".." in DIRNAME */ 75 76 if (M_DRDELIM(arg[1])) /* drive-specified pathnames */ 77 path = arg+2; 78 else 79 path = arg; 80 81 if (path[1]=='\0'&&M_FSDELIM(*path)) /* "/", or drive analog */ 82 return arg; 83 84 cp = strchr(path, '\0'); 85 cp--; 86 87 while (cp != path && M_FSDELIM(*cp)) 88 *(cp--) = '\0'; 89 90 for (;cp>path && !M_FSDELIM(*cp); cp--) 91 ; 92 93 if (!M_FSDELIM(*cp)) 94 if (type==DIRNAME && path!=arg) { 95 *path = '\0'; 96 return arg; /* curdir on the specified drive */ 97 } else 98 return (type==DIRNAME)?curdir:path; 99 else if (cp == path && type == DIRNAME) { 100 cp[1] = '\0'; 101 return arg; /* root directory involved */ 102 } else if (cp == path && cp[1] == '\0') 103 return(arg); 104 else if (type == BASENAME) 105 return ++cp; 106 *cp = '\0'; 107 return arg; 108 } 109 110 /*f 111 * Finds the dirname of the given file. Spec1170 conformant. 112 */ 113 char * 114 dirname(char *arg) 115 { 116 return(basedir(arg, DIRNAME)); 117 } 118 119 /*f 120 * Finds the basename of the given file. Spec1170 conformant. 121 */ 122 char * 123 basename(char *arg) 124 { 125 return(basedir(arg, BASENAME)); 126 } 127 128 #ifdef TEST_MAIN_BASE_C 129 #include <stdio.h> 130 131 int main(int argc, char **argv) 132 { 133 int cnt; 134 char arg[128]; 135 char *tmp; 136 137 if (argc>1) { 138 for (cnt=argc--;argc;argc--) { 139 tmp = strdup(argv[cnt-argc]); 140 printf("%s\t%s\n", 141 dirname(argv[cnt-argc]), 142 basename(tmp)); 143 free(tmp); 144 } 145 return 0; 146 } 147 148 printf("enter pathnames less than 128 chars. enter 'q' to quit.\n"); 149 150 while(gets(arg)) 151 if (!strcmp(arg, "q")) 152 break; 153 else { 154 tmp = strdup(arg); 155 printf("%s\t%s\n", dirname(arg), basename(tmp)); 156 free(tmp); 157 } 158 159 return 0; 160 } 161 #endif /* TEST_MAIN_BASE_C */ 162