dirname.c revision 108152
165294Sdes/* 265294Sdes * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 365294Sdes * All rights reserved. 465294Sdes * 565294Sdes * Redistribution and use in source and binary forms, with or without 665294Sdes * modification, are permitted provided that the following conditions 765294Sdes * are met: 865294Sdes * 1. Redistributions of source code must retain the above copyright 965294Sdes * notice, this list of conditions and the following disclaimer. 1065294Sdes * 2. Redistributions in binary form must reproduce the above copyright 1165294Sdes * notice, this list of conditions and the following disclaimer in the 1265294Sdes * documentation and/or other materials provided with the distribution. 1365294Sdes * 3. The name of the author may not be used to endorse or promote products 1465294Sdes * derived from this software without specific prior written permission. 1565294Sdes * 1665294Sdes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1765294Sdes * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 1865294Sdes * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 1965294Sdes * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2065294Sdes * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2165294Sdes * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2265294Sdes * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2365294Sdes * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2465294Sdes * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2565294Sdes * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2665294Sdes */ 2765294Sdes 2890016Sbde#if 0 2965294Sdes#ifndef lint 3065294Sdesstatic char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; 3190016Sbde#endif /* not lint */ 3289999Sobrien#endif 3390016Sbde#include <sys/cdefs.h> 3489999Sobrien__FBSDID("$FreeBSD: head/lib/libc/gen/dirname.c 108152 2002-12-21 07:12:35Z bbraun $"); 3565294Sdes 3665294Sdes#include <errno.h> 3765294Sdes#include <libgen.h> 3865294Sdes#include <string.h> 3965294Sdes#include <sys/param.h> 4065294Sdes 4165294Sdeschar * 4265294Sdesdirname(path) 4365294Sdes const char *path; 4465294Sdes{ 45108152Sbbraun static char *bname = NULL; 4690041Sobrien const char *endp; 4765294Sdes 48108152Sbbraun if (bname == NULL) { 49108152Sbbraun bname = (char *)malloc(MAXPATHLEN); 50108152Sbbraun if (bname == NULL) 51108152Sbbraun return(NULL); 52108152Sbbraun } 53108152Sbbraun 5465294Sdes /* Empty or NULL string gets treated as "." */ 5565294Sdes if (path == NULL || *path == '\0') { 5665294Sdes (void)strcpy(bname, "."); 5765294Sdes return(bname); 5865294Sdes } 5965294Sdes 6065294Sdes /* Strip trailing slashes */ 6165294Sdes endp = path + strlen(path) - 1; 6265294Sdes while (endp > path && *endp == '/') 6365294Sdes endp--; 6465294Sdes 6565294Sdes /* Find the start of the dir */ 6665294Sdes while (endp > path && *endp != '/') 6765294Sdes endp--; 6865294Sdes 6965294Sdes /* Either the dir is "/" or there are no slashes */ 7065294Sdes if (endp == path) { 7165294Sdes (void)strcpy(bname, *endp == '/' ? "/" : "."); 7265294Sdes return(bname); 7365294Sdes } else { 7465294Sdes do { 7565294Sdes endp--; 7665294Sdes } while (endp > path && *endp == '/'); 7765294Sdes } 7865294Sdes 79108152Sbbraun if (endp - path + 2 > MAXPATHLEN) { 8065294Sdes errno = ENAMETOOLONG; 8165294Sdes return(NULL); 8265294Sdes } 8365294Sdes (void)strncpy(bname, path, endp - path + 1); 8465294Sdes bname[endp - path + 1] = '\0'; 8565294Sdes return(bname); 8665294Sdes} 87