diff options
Diffstat (limited to 'opkg-opk/dirent.c')
-rw-r--r-- | opkg-opk/dirent.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/opkg-opk/dirent.c b/opkg-opk/dirent.c index 0080d44..9d27cfd 100644 --- a/opkg-opk/dirent.c +++ b/opkg-opk/dirent.c @@ -115,3 +115,59 @@ opkg_opk_dirent_name_prefix(struct opkg_opk_dirent *dirent, int is_dir, return OPKG_OPK_OK; } + +static char * +_opkg_opk_dirent_name_alloc(struct opkg_opk_dirent *dirent, int is_dir, + char **cur, size_t *buf_len) +{ + size_t len; + int sep; + char *buf; + + len = strlen(dirent->name); + if (*buf_len > 1 /* 1 for NUL */ || is_dir) { + /* Not last node, or is a directory, so append separator. */ + sep = 1; /* Used in math below, so must be 1, not just != 0. */ + ++len; + } else { + /* Last node (first in recursion), so don't append separator. */ + sep = 0; + } + *buf_len += len; + + if (dirent->parent == NULL) { + buf = malloc(*buf_len); + if (buf == NULL) { + return NULL; + } + *cur = buf; + } else if ((buf = _opkg_opk_dirent_name_alloc(dirent->parent, is_dir, + cur, buf_len)) == NULL) { + return NULL; + } + + /* Copy node name and possibly separator suffix. */ + memcpy(*cur, dirent->name, len - sep); + *cur += len - sep; + if (sep == 1) { + **cur = '/'; + *cur += 1; + } + + return buf; +} + +char * +opkg_opk_dirent_name_alloc(struct opkg_opk_dirent *dirent, int is_dir) +{ + char *buf; + char *cur = NULL; + size_t buf_len = 1; /* 1 for NUL */ + + if ((buf = _opkg_opk_dirent_name_alloc(dirent, is_dir, &cur, &buf_len)) + == NULL) { + return NULL; + } + *cur = '\0'; + return buf; +} |