xref: /netbsd-src/usr.bin/dirname/dirname.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: dirname.c,v 1.8 2003/08/07 11:13:34 agc Exp $	*/
2 
3 /*-
4  * Copyright (c) 1991, 1993, 1994
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\
35 	The Regents of the University of California.  All rights reserved.\n");
36 #endif /* not lint */
37 
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)dirname.c	8.4 (Berkeley) 5/4/95";
41 #endif
42 __RCSID("$NetBSD: dirname.c,v 1.8 2003/08/07 11:13:34 agc Exp $");
43 #endif /* not lint */
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <locale.h>
48 #include <unistd.h>
49 
50 int	main __P((int, char **));
51 static void usage __P((void));
52 
53 int
54 main(argc, argv)
55 	int argc;
56 	char **argv;
57 {
58 	register char *p;
59 	int ch;
60 
61 	setlocale(LC_ALL, "");
62 
63 	while ((ch = getopt(argc, argv, "")) != -1)
64 		switch(ch) {
65 		case '?':
66 		default:
67 			usage();
68 		}
69 	argc -= optind;
70 	argv += optind;
71 
72 	if (argc != 1)
73 		usage();
74 
75 	/*
76 	 * (1) If string is //, skip steps (2) through (5).
77 	 * (2) If string consists entirely of slash characters, string
78 	 *     shall be set to a single slash character.  In this case,
79 	 *     skip steps (3) through (8).
80 	 */
81 	for (p = *argv;; ++p) {
82 		if (!*p) {
83 			if (p > *argv)
84 				(void)printf("/\n");
85 			else
86 				(void)printf(".\n");
87 			exit(0);
88 		}
89 		if (*p != '/')
90 			break;
91 	}
92 
93 	/*
94 	 * (3) If there are any trailing slash characters in string, they
95 	 *     shall be removed.
96 	 */
97 	for (; *p; ++p);
98 	while (*--p == '/')
99 		continue;
100 	*++p = '\0';
101 
102 	/*
103 	 * (4) If there are no slash characters remaining in string,
104 	 *     string shall be set to a single period character.  In this
105 	 *     case skip steps (5) through (8).
106 	 *
107 	 * (5) If there are any trailing nonslash characters in string,
108 	 *     they shall be removed.
109 	 */
110 	while (--p >= *argv)
111 		if (*p == '/')
112 			break;
113 	++p;
114 	if (p == *argv) {
115 		(void)printf(".\n");
116 		exit(0);
117 	}
118 
119 	/*
120 	 * (6) If the remaining string is //, it is implementation defined
121 	 *     whether steps (7) and (8) are skipped or processed.
122 	 *
123 	 * This case has already been handled, as part of steps (1) and (2).
124 	 */
125 
126 	/*
127 	 * (7) If there are any trailing slash characters in string, they
128 	 *     shall be removed.
129 	 */
130 	while (--p >= *argv)
131 		if (*p != '/')
132 			break;
133 	++p;
134 
135 	/*
136 	 * (8) If the remaining string is empty, string shall be set to
137 	 *     a single slash character.
138 	 */
139 	*p = '\0';
140 	(void)printf("%s\n", p == *argv ? "/" : *argv);
141 	exit(0);
142 }
143 
144 static void
145 usage()
146 {
147 
148 	(void)fprintf(stderr, "usage: dirname path\n");
149 	exit(1);
150 }
151 
152