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 <sys/cdefs.h> 20e2f68161SEd Schouten __FBSDID("$FreeBSD$"); 21e2f68161SEd Schouten 22e2f68161SEd Schouten #include <errno.h> 23e2f68161SEd Schouten #include <libgen.h> 24e2f68161SEd Schouten #include <stdlib.h> 25e2f68161SEd Schouten #include <string.h> 26e2f68161SEd Schouten #include <sys/param.h> 27e2f68161SEd Schouten 28*d14f60e9SAlan Somers char * __freebsd11_dirname(char *path); 29*d14f60e9SAlan Somers 30e2f68161SEd Schouten char * 31e2f68161SEd Schouten __freebsd11_dirname(char *path) 32e2f68161SEd Schouten { 33e2f68161SEd Schouten static char *dname = NULL; 34e2f68161SEd Schouten size_t len; 35e2f68161SEd Schouten const char *endp; 36e2f68161SEd Schouten 37e2f68161SEd Schouten if (dname == NULL) { 38e2f68161SEd Schouten dname = (char *)malloc(MAXPATHLEN); 39e2f68161SEd Schouten if (dname == NULL) 40e2f68161SEd Schouten return(NULL); 41e2f68161SEd Schouten } 42e2f68161SEd Schouten 43e2f68161SEd Schouten /* Empty or NULL string gets treated as "." */ 44e2f68161SEd Schouten if (path == NULL || *path == '\0') { 45e2f68161SEd Schouten dname[0] = '.'; 46e2f68161SEd Schouten dname[1] = '\0'; 47e2f68161SEd Schouten return (dname); 48e2f68161SEd Schouten } 49e2f68161SEd Schouten 50e2f68161SEd Schouten /* Strip any trailing slashes */ 51e2f68161SEd Schouten endp = path + strlen(path) - 1; 52e2f68161SEd Schouten while (endp > path && *endp == '/') 53e2f68161SEd Schouten endp--; 54e2f68161SEd Schouten 55e2f68161SEd Schouten /* Find the start of the dir */ 56e2f68161SEd Schouten while (endp > path && *endp != '/') 57e2f68161SEd Schouten endp--; 58e2f68161SEd Schouten 59e2f68161SEd Schouten /* Either the dir is "/" or there are no slashes */ 60e2f68161SEd Schouten if (endp == path) { 61e2f68161SEd Schouten dname[0] = *endp == '/' ? '/' : '.'; 62e2f68161SEd Schouten dname[1] = '\0'; 63e2f68161SEd Schouten return (dname); 64e2f68161SEd Schouten } else { 65e2f68161SEd Schouten /* Move forward past the separating slashes */ 66e2f68161SEd Schouten do { 67e2f68161SEd Schouten endp--; 68e2f68161SEd Schouten } while (endp > path && *endp == '/'); 69e2f68161SEd Schouten } 70e2f68161SEd Schouten 71e2f68161SEd Schouten len = endp - path + 1; 72e2f68161SEd Schouten if (len >= MAXPATHLEN) { 73e2f68161SEd Schouten errno = ENAMETOOLONG; 74e2f68161SEd Schouten return (NULL); 75e2f68161SEd Schouten } 76e2f68161SEd Schouten memcpy(dname, path, len); 77e2f68161SEd Schouten dname[len] = '\0'; 78e2f68161SEd Schouten return (dname); 79e2f68161SEd Schouten } 80e2f68161SEd Schouten 81e2f68161SEd Schouten __sym_compat(dirname, __freebsd11_dirname, FBSD_1.0); 82