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