--- sftp-common.c 2006-05-11 22:36:23.000000000 -0700 +++ sftp-common.c_cache 2006-05-11 22:52:54.000000000 -0700 @@ -34,6 +34,9 @@ #include "sftp.h" #include "sftp-common.h" +#define GROUP_CACHE_SIZE 5 +#define PW_CACHE_SIZE 5 + /* Clear contents of attributes structure */ void attrib_clear(Attrib *a) @@ -170,6 +173,65 @@ /* NOTREACHED */ } +struct group* getgrgid_cached(gid_t gid) +{ + static struct group *groupcache = NULL; + struct group *result; + int i; + + if (groupcache == NULL) { + groupcache = (struct group *)calloc(GROUP_CACHE_SIZE, sizeof(struct group)); + } + + for (i = 0; i < GROUP_CACHE_SIZE; i++) { + if (groupcache[i].gr_gid == gid && groupcache[i].gr_name != NULL) { + return &(groupcache[i]); + } + } + + result = getgrgid(gid); + if (result != NULL && result->gr_name != NULL) { + for (i = 0; i < GROUP_CACHE_SIZE; i++) { + if (groupcache[i].gr_name == NULL) { + groupcache[i].gr_gid = gid; + groupcache[i].gr_name = strdup(result->gr_name); + } + } + } + return result; +} + +struct passwd* getpwuid_cached(uid_t uid) +{ + static struct passwd *pwcache = NULL; + struct passwd *result; + int i; + + if (pwcache == NULL) { + pwcache = (struct passwd *)calloc(PW_CACHE_SIZE, sizeof(struct passwd)); + } + + for (i = 0; i < PW_CACHE_SIZE; i++) { + if (pwcache[i].pw_name != NULL && pwcache[i].pw_uid == uid) { + return &(pwcache[i]); + } + } + + result = getpwuid(uid); + if (result != NULL && result->pw_name != NULL) { + for (i = 0; i < PW_CACHE_SIZE; i++) { + if (pwcache[i].pw_name == NULL) { + pwcache[i].pw_uid = uid; + pwcache[i].pw_name = strdup(result->pw_name); + } + } + } + return result; +} + + /* * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh */ @@ -184,13 +246,13 @@ char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; strmode(st->st_mode, mode); - if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { + if (!remote && (pw = getpwuid_cached(st->st_uid)) != NULL) { user = pw->pw_name; } else { snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); user = ubuf; } - if (!remote && (gr = getgrgid(st->st_gid)) != NULL) { + if (!remote && (gr = getgrgid_cached(st->st_gid)) != NULL) { group = gr->gr_name; } else { snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);