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 *
basedir(char * arg,int type)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 *
dirname(char * arg)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 *
basename(char * arg)123 basename(char *arg)
124 {
125 return(basedir(arg, BASENAME));
126 }
127
128 #ifdef TEST_MAIN_BASE_C
129 #include <stdio.h>
130
main(int argc,char ** argv)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