1e2f68161SEd Schouten /* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */
2e2f68161SEd Schouten
3e2f68161SEd Schouten /*
4e2f68161SEd Schouten * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
5e2f68161SEd Schouten *
6e2f68161SEd Schouten * Permission to use, copy, modify, and distribute this software for any
7e2f68161SEd Schouten * purpose with or without fee is hereby granted, provided that the above
8e2f68161SEd Schouten * copyright notice and this permission notice appear in all copies.
9e2f68161SEd Schouten *
10e2f68161SEd Schouten * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11e2f68161SEd Schouten * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12e2f68161SEd Schouten * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13e2f68161SEd Schouten * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14e2f68161SEd Schouten * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15e2f68161SEd Schouten * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16e2f68161SEd Schouten * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17e2f68161SEd Schouten */
18e2f68161SEd Schouten
19e2f68161SEd Schouten #include <errno.h>
20e2f68161SEd Schouten #include <libgen.h>
21e2f68161SEd Schouten #include <stdlib.h>
22e2f68161SEd Schouten #include <string.h>
23e2f68161SEd Schouten #include <sys/param.h>
24e2f68161SEd Schouten
25*d14f60e9SAlan Somers char * __freebsd11_dirname(char *path);
26*d14f60e9SAlan Somers
27e2f68161SEd Schouten char *
__freebsd11_dirname(char * path)28e2f68161SEd Schouten __freebsd11_dirname(char *path)
29e2f68161SEd Schouten {
30e2f68161SEd Schouten static char *dname = NULL;
31e2f68161SEd Schouten size_t len;
32e2f68161SEd Schouten const char *endp;
33e2f68161SEd Schouten
34e2f68161SEd Schouten if (dname == NULL) {
35e2f68161SEd Schouten dname = (char *)malloc(MAXPATHLEN);
36e2f68161SEd Schouten if (dname == NULL)
37e2f68161SEd Schouten return(NULL);
38e2f68161SEd Schouten }
39e2f68161SEd Schouten
40e2f68161SEd Schouten /* Empty or NULL string gets treated as "." */
41e2f68161SEd Schouten if (path == NULL || *path == '\0') {
42e2f68161SEd Schouten dname[0] = '.';
43e2f68161SEd Schouten dname[1] = '\0';
44e2f68161SEd Schouten return (dname);
45e2f68161SEd Schouten }
46e2f68161SEd Schouten
47e2f68161SEd Schouten /* Strip any trailing slashes */
48e2f68161SEd Schouten endp = path + strlen(path) - 1;
49e2f68161SEd Schouten while (endp > path && *endp == '/')
50e2f68161SEd Schouten endp--;
51e2f68161SEd Schouten
52e2f68161SEd Schouten /* Find the start of the dir */
53e2f68161SEd Schouten while (endp > path && *endp != '/')
54e2f68161SEd Schouten endp--;
55e2f68161SEd Schouten
56e2f68161SEd Schouten /* Either the dir is "/" or there are no slashes */
57e2f68161SEd Schouten if (endp == path) {
58e2f68161SEd Schouten dname[0] = *endp == '/' ? '/' : '.';
59e2f68161SEd Schouten dname[1] = '\0';
60e2f68161SEd Schouten return (dname);
61e2f68161SEd Schouten } else {
62e2f68161SEd Schouten /* Move forward past the separating slashes */
63e2f68161SEd Schouten do {
64e2f68161SEd Schouten endp--;
65e2f68161SEd Schouten } while (endp > path && *endp == '/');
66e2f68161SEd Schouten }
67e2f68161SEd Schouten
68e2f68161SEd Schouten len = endp - path + 1;
69e2f68161SEd Schouten if (len >= MAXPATHLEN) {
70e2f68161SEd Schouten errno = ENAMETOOLONG;
71e2f68161SEd Schouten return (NULL);
72e2f68161SEd Schouten }
73e2f68161SEd Schouten memcpy(dname, path, len);
74e2f68161SEd Schouten dname[len] = '\0';
75e2f68161SEd Schouten return (dname);
76e2f68161SEd Schouten }
77e2f68161SEd Schouten
78e2f68161SEd Schouten __sym_compat(dirname, __freebsd11_dirname, FBSD_1.0);
79