dirname.c revision 108152
175584Sru/* 275584Sru * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 375584Sru * All rights reserved. 4104862Sru * 575584Sru * Redistribution and use in source and binary forms, with or without 675584Sru * modification, are permitted provided that the following conditions 775584Sru * are met: 875584Sru * 1. Redistributions of source code must retain the above copyright 975584Sru * notice, this list of conditions and the following disclaimer. 1075584Sru * 2. Redistributions in binary form must reproduce the above copyright 1175584Sru * notice, this list of conditions and the following disclaimer in the 1275584Sru * documentation and/or other materials provided with the distribution. 1375584Sru * 3. The name of the author may not be used to endorse or promote products 1475584Sru * derived from this software without specific prior written permission. 1575584Sru * 1675584Sru * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1775584Sru * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 1875584Sru * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 1975584Sru * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2075584Sru * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2175584Sru * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22104862Sru * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2375584Sru * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2475584Sru * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2575584Sru * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2675584Sru */ 2775584Sru 2875584Sru#if 0 2975584Sru#ifndef lint 3075584Srustatic char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; 3175584Sru#endif /* not lint */ 3275584Sru#endif 3375584Sru#include <sys/cdefs.h> 3475584Sru__FBSDID("$FreeBSD: head/lib/libc/gen/dirname.c 108152 2002-12-21 07:12:35Z bbraun $"); 3575584Sru 3675584Sru#include <errno.h> 3775584Sru#include <libgen.h> 3875584Sru#include <string.h> 3975584Sru#include <sys/param.h> 4075584Sru 4175584Sruchar * 4275584Srudirname(path) 4375584Sru const char *path; 4475584Sru{ 4575584Sru static char *bname = NULL; 4675584Sru const char *endp; 4775584Sru 4875584Sru if (bname == NULL) { 4975584Sru bname = (char *)malloc(MAXPATHLEN); 5075584Sru if (bname == NULL) 5175584Sru return(NULL); 5275584Sru } 5375584Sru 5475584Sru /* Empty or NULL string gets treated as "." */ 5575584Sru if (path == NULL || *path == '\0') { 5675584Sru (void)strcpy(bname, "."); 5775584Sru return(bname); 5875584Sru } 5975584Sru 6075584Sru /* Strip trailing slashes */ 6175584Sru endp = path + strlen(path) - 1; 6275584Sru while (endp > path && *endp == '/') 6375584Sru endp--; 6475584Sru 6575584Sru /* Find the start of the dir */ 6675584Sru while (endp > path && *endp != '/') 6775584Sru endp--; 6875584Sru 6975584Sru /* Either the dir is "/" or there are no slashes */ 7075584Sru if (endp == path) { 7175584Sru (void)strcpy(bname, *endp == '/' ? "/" : "."); 7275584Sru return(bname); 7375584Sru } else { 7475584Sru do { 7575584Sru endp--; 7675584Sru } while (endp > path && *endp == '/'); 7775584Sru } 7875584Sru 7975584Sru if (endp - path + 2 > MAXPATHLEN) { 80104862Sru errno = ENAMETOOLONG; 8175584Sru return(NULL); 8275584Sru } 8375584Sru (void)strncpy(bname, path, endp - path + 1); 8475584Sru bname[endp - path + 1] = '\0'; 8575584Sru return(bname); 8675584Sru} 8775584Sru