/* * Copyright (c) 2003 Gunnar Ritter * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute * it freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ /* Sccsid @(#)getdir.c 1.20 (gritter) 5/14/06 */ #include #include #include #include #include #include #include "getdir.h" #define DIBSIZE 5120 struct getdb { #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ && !defined (__DragonFly__) && !defined (__APPLE__) off_t g_offs; #else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ long g_offs; #endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ struct dirent *g_dirp; const char *g_path; struct direc g_dic; union { char g_dirbuf[DIBSIZE+1]; struct dirent g_dummy[1]; } g_u; int g_num; int g_fd; }; struct getdb * getdb_alloc(const char *path, int fd) { struct getdb *db; if ((db = malloc(sizeof *db)) == NULL) return NULL; db->g_dirp = NULL; db->g_offs = 0; db->g_fd = fd; db->g_path = path; return db; } void getdb_free(struct getdb *db) { free(db); } struct direc * getdir(struct getdb *db, int *err) { int reclen; *err = 0; while (db->g_dirp == NULL) { /*LINTED*/ db->g_num = getdents(db->g_fd, (struct dirent *)db->g_u.g_dirbuf, DIBSIZE); if (db->g_num <= 0) { if (db->g_num < 0) *err = errno; db->g_offs = 0; return NULL; } /*LINTED*/ db->g_dirp = (struct dirent *)db->g_u.g_dirbuf; while (db->g_dirp && #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ && !defined (__DragonFly__) && !defined (__APPLE__) db->g_dirp->d_ino == 0 #else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ (db->g_dirp->d_fileno == 0 #ifdef DT_WHT || db->g_dirp->d_type == DT_WHT #endif ) #endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ ) { next: #ifndef __DragonFly__ reclen = db->g_dirp->d_reclen; #else reclen = _DIRENT_DIRSIZ(db->g_dirp); #endif if ((db->g_num -= reclen) == 0 || reclen == 0) db->g_dirp = NULL; else db->g_dirp = /*LINTED*/ (struct dirent *)((char *)db->g_dirp + reclen); } } #if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ && !defined (__DragonFly__) && !defined (__APPLE__) if (db->g_dirp->d_ino == 0) goto next; db->g_dic.d_ino = db->g_dirp->d_ino; #else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ if (db->g_dirp->d_fileno == 0 #ifdef DT_WHT || db->g_dirp->d_type == DT_WHT #endif ) { goto next; } db->g_dic.d_ino = db->g_dirp->d_fileno; #endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ db->g_dic.d_name = db->g_dirp->d_name; #ifndef __DragonFly__ reclen = db->g_dirp->d_reclen; #else reclen = _DIRENT_DIRSIZ(db->g_dirp); #endif if ((db->g_num -= reclen) == 0 || reclen == 0) db->g_dirp = NULL; else /*LINTED*/ db->g_dirp = (struct dirent *)((char *)db->g_dirp + reclen); return &(db->g_dic); }