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