dirname.c (7b1fac00358d75b00a83566efb93372101958cdd) | dirname.c (1250db81390606572908abd88d78c1f2fa5a1832) |
---|---|
1/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ | 1/* $OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */ 2/* $FreeBSD$ */ |
2 3/* | 3 4/* |
4 * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com> | 5 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 6 * All rights reserved. |
5 * | 7 * |
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. | 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. |
9 * | 18 * |
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. | 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
17 */ 18 | 29 */ 30 |
19#include <sys/cdefs.h> 20__FBSDID("$FreeBSD$"); | 31#ifndef lint 32static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $"; 33#endif /* not lint */ |
21 22#include <errno.h> 23#include <libgen.h> | 34 35#include <errno.h> 36#include <libgen.h> |
24#include <stdlib.h> | |
25#include <string.h> 26#include <sys/param.h> 27 28char * | 37#include <string.h> 38#include <sys/param.h> 39 40char * |
29dirname(const char *path) | 41dirname(path) 42 const char *path; |
30{ | 43{ |
31 static char *dname = NULL; 32 size_t len; 33 const char *endp; | 44 static char bname[MAXPATHLEN]; 45 register const char *endp; |
34 | 46 |
35 if (dname == NULL) { 36 dname = (char *)malloc(MAXPATHLEN); 37 if (dname == NULL) 38 return(NULL); 39 } 40 | |
41 /* Empty or NULL string gets treated as "." */ 42 if (path == NULL || *path == '\0') { | 47 /* Empty or NULL string gets treated as "." */ 48 if (path == NULL || *path == '\0') { |
43 dname[0] = '.'; 44 dname[1] = '\0'; 45 return (dname); | 49 (void)strcpy(bname, "."); 50 return(bname); |
46 } 47 | 51 } 52 |
48 /* Strip any trailing slashes */ | 53 /* Strip trailing slashes */ |
49 endp = path + strlen(path) - 1; 50 while (endp > path && *endp == '/') 51 endp--; 52 53 /* Find the start of the dir */ 54 while (endp > path && *endp != '/') 55 endp--; 56 57 /* Either the dir is "/" or there are no slashes */ 58 if (endp == path) { | 54 endp = path + strlen(path) - 1; 55 while (endp > path && *endp == '/') 56 endp--; 57 58 /* Find the start of the dir */ 59 while (endp > path && *endp != '/') 60 endp--; 61 62 /* Either the dir is "/" or there are no slashes */ 63 if (endp == path) { |
59 dname[0] = *endp == '/' ? '/' : '.'; 60 dname[1] = '\0'; 61 return (dname); | 64 (void)strcpy(bname, *endp == '/' ? "/" : "."); 65 return(bname); |
62 } else { | 66 } else { |
63 /* Move forward past the separating slashes */ | |
64 do { 65 endp--; 66 } while (endp > path && *endp == '/'); 67 } 68 | 67 do { 68 endp--; 69 } while (endp > path && *endp == '/'); 70 } 71 |
69 len = endp - path + 1; 70 if (len >= MAXPATHLEN) { | 72 if (endp - path + 1 > sizeof(bname)) { |
71 errno = ENAMETOOLONG; | 73 errno = ENAMETOOLONG; |
72 return (NULL); | 74 return(NULL); |
73 } | 75 } |
74 memcpy(dname, path, len); 75 dname[len] = '\0'; 76 return (dname); | 76 (void)strncpy(bname, path, endp - path + 1); 77 bname[endp - path + 1] = '\0'; 78 return(bname); |
77} | 79} |