Home | History | Annotate | Download | only in openbsd-compat
      1 /*	$OpenBSD: basename.c,v 1.14 2005/08/08 08:05:33 espie Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller (at) courtesan.com>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 /* OPENBSD ORIGINAL: lib/libc/gen/basename.c */
     20 
     21 #include "includes.h"
     22 #ifndef HAVE_BASENAME
     23 #include <errno.h>
     24 #include <string.h>
     25 
     26 char *
     27 basename(const char *path)
     28 {
     29 	static char bname[MAXPATHLEN];
     30 	size_t len;
     31 	const char *endp, *startp;
     32 
     33 	/* Empty or NULL string gets treated as "." */
     34 	if (path == NULL || *path == '\0') {
     35 		bname[0] = '.';
     36 		bname[1] = '\0';
     37 		return (bname);
     38 	}
     39 
     40 	/* Strip any trailing slashes */
     41 	endp = path + strlen(path) - 1;
     42 	while (endp > path && *endp == '/')
     43 		endp--;
     44 
     45 	/* All slashes becomes "/" */
     46 	if (endp == path && *endp == '/') {
     47 		bname[0] = '/';
     48 		bname[1] = '\0';
     49 		return (bname);
     50 	}
     51 
     52 	/* Find the start of the base */
     53 	startp = endp;
     54 	while (startp > path && *(startp - 1) != '/')
     55 		startp--;
     56 
     57 	len = endp - startp + 1;
     58 	if (len >= sizeof(bname)) {
     59 		errno = ENAMETOOLONG;
     60 		return (NULL);
     61 	}
     62 	memcpy(bname, startp, len);
     63 	bname[len] = '\0';
     64 	return (bname);
     65 }
     66 
     67 #endif /* !defined(HAVE_BASENAME) */
     68