1157016Sdes/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */ 2126274Sdes 398937Sdes/* 4157016Sdes * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com> 598937Sdes * 6124208Sdes * Permission to use, copy, modify, and distribute this software for any 7124208Sdes * purpose with or without fee is hereby granted, provided that the above 8124208Sdes * copyright notice and this permission notice appear in all copies. 998937Sdes * 10124208Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11124208Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12124208Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13124208Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14124208Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15124208Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16124208Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1798937Sdes */ 1898937Sdes 19157016Sdes/* OPENBSD ORIGINAL: lib/libc/gen/dirname.c */ 20157016Sdes 2198937Sdes#include "includes.h" 2298937Sdes#ifndef HAVE_DIRNAME 2398937Sdes 2498937Sdes#include <errno.h> 2598937Sdes#include <string.h> 2698937Sdes#include <sys/param.h> 2798937Sdes 2898937Sdeschar * 29124208Sdesdirname(const char *path) 3098937Sdes{ 31157016Sdes static char dname[MAXPATHLEN]; 32157016Sdes size_t len; 33157016Sdes const char *endp; 3498937Sdes 3598937Sdes /* Empty or NULL string gets treated as "." */ 3698937Sdes if (path == NULL || *path == '\0') { 37157016Sdes dname[0] = '.'; 38157016Sdes dname[1] = '\0'; 39157016Sdes return (dname); 4098937Sdes } 4198937Sdes 42157016Sdes /* Strip any trailing slashes */ 4398937Sdes endp = path + strlen(path) - 1; 4498937Sdes while (endp > path && *endp == '/') 4598937Sdes endp--; 4698937Sdes 4798937Sdes /* Find the start of the dir */ 4898937Sdes while (endp > path && *endp != '/') 4998937Sdes endp--; 5098937Sdes 5198937Sdes /* Either the dir is "/" or there are no slashes */ 5298937Sdes if (endp == path) { 53157016Sdes dname[0] = *endp == '/' ? '/' : '.'; 54157016Sdes dname[1] = '\0'; 55157016Sdes return (dname); 5698937Sdes } else { 57157016Sdes /* Move forward past the separating slashes */ 5898937Sdes do { 5998937Sdes endp--; 6098937Sdes } while (endp > path && *endp == '/'); 6198937Sdes } 6298937Sdes 63157016Sdes len = endp - path + 1; 64157016Sdes if (len >= sizeof(dname)) { 6598937Sdes errno = ENAMETOOLONG; 66157016Sdes return (NULL); 6798937Sdes } 68157016Sdes memcpy(dname, path, len); 69157016Sdes dname[len] = '\0'; 70157016Sdes return (dname); 7198937Sdes} 7298937Sdes#endif 73