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@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 #include <sys/cdefs.h> 20 __FBSDID("$FreeBSD$"); 21 22 #include <errno.h> 23 #include <libgen.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <sys/param.h> 27 28 char * __freebsd11_basename_r(const char *path, char *bname); 29 char * __freebsd11_basename(char *path); 30 31 char * 32 __freebsd11_basename_r(const char *path, char *bname) 33 { 34 const char *endp, *startp; 35 size_t len; 36 37 /* Empty or NULL string gets treated as "." */ 38 if (path == NULL || *path == '\0') { 39 bname[0] = '.'; 40 bname[1] = '\0'; 41 return (bname); 42 } 43 44 /* Strip any trailing slashes */ 45 endp = path + strlen(path) - 1; 46 while (endp > path && *endp == '/') 47 endp--; 48 49 /* All slashes becomes "/" */ 50 if (endp == path && *endp == '/') { 51 bname[0] = '/'; 52 bname[1] = '\0'; 53 return (bname); 54 } 55 56 /* Find the start of the base */ 57 startp = endp; 58 while (startp > path && *(startp - 1) != '/') 59 startp--; 60 61 len = endp - startp + 1; 62 if (len >= MAXPATHLEN) { 63 errno = ENAMETOOLONG; 64 return (NULL); 65 } 66 memcpy(bname, startp, len); 67 bname[len] = '\0'; 68 return (bname); 69 } 70 71 char * 72 __freebsd11_basename(char *path) 73 { 74 static char *bname = NULL; 75 76 if (bname == NULL) { 77 bname = (char *)malloc(MAXPATHLEN); 78 if (bname == NULL) 79 return (NULL); 80 } 81 return (__freebsd11_basename_r(path, bname)); 82 } 83 84 __sym_compat(basename_r, __freebsd11_basename_r, FBSD_1.2); 85 __sym_compat(basename, __freebsd11_basename, FBSD_1.0); 86