char *uid2str( uid_t uid, char *username ) { struct passwd *p = GetPwUid( uid ); if ( p != NULL ) strcpy( username, p->pw_name ); else sprintf( username, "%d", ( int ) uid ); return username; }
char* GetUserFromPid(pid_t pid) { #if defined(__linux__) // Get effective owner of pid from procfs std::stringstream ss; ss << "/proc/" << pid; std::string path; ss >> path; return GetFileOwner(path.c_str()); #elif defined(__APPLE__) && defined(__MACH__) // Get effective owner of pid from sysctl struct kinfo_proc oldp; size_t oldlenp = sizeof(oldp); int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; u_int namelen = sizeof(name)/sizeof(int); // Read-only query int ret = sysctl(name, namelen, &oldp, &oldlenp, NULL, 0); if (ret != 0 || oldlenp == 0) { errno = ERROR_GEN_FAILURE; return NULL; } return GetPwUid(oldp.kp_eproc.e_ucred.cr_uid); #else return NULL; #endif }
static inline void print_entry(const wagon_t *id, const attr_set_t * attrs) { #ifdef ATTR_INDEX_status if (prog_options.match_status) { if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != prog_options.status)) { /* no match -> no display */ return; } } #endif if (prog_options.ls) { const char * type; char date_str[128]; char mode_str[128]; char uname[LOGIN_NAME_MAX]; char gname[LOGIN_NAME_MAX]; struct passwd *passwd; struct group *group; #ifdef ATTR_INDEX_status const char * status_str = ""; /* add status after type */ if (ATTR_MASK_TEST(attrs, status) && (ATTR(attrs, status) != STATUS_UNKNOWN)) status_str = db_status2str(ATTR(attrs, status), 1); /* 1 for brief */ #define STATUS_FORMAT "%-10s" #define STATUS_VAL ,status_str #else #define STATUS_FORMAT "" #define STATUS_VAL #endif /* type2char */ if (!ATTR_MASK_TEST(attrs, type)) type = "?"; else type = type2char(ATTR(attrs, type)); memset(mode_str, 0, sizeof(mode_str)); mode_string(ATTR(attrs, mode), mode_str); if (!ATTR_MASK_TEST(attrs, last_mod)) strcpy(date_str, ""); else { time_t tt; struct tm stm; tt = ATTR(attrs, last_mod); strftime(date_str, 128, "%Y/%m/%d %T", localtime_r(&tt, &stm)); } /* UID/GID to username/group. */ passwd = GetPwUid(ATTR(attrs, uid)); if (passwd) sprintf(uname, "%-10s", passwd->pw_name); else sprintf(uname, "%10u", ATTR(attrs, uid)); group = GetGrGid(ATTR(attrs, gid)); if (group) sprintf(gname, "%-10s", group->gr_name); else sprintf(gname, "%10u", ATTR(attrs, gid)); if (ATTR_MASK_TEST(attrs, type) && !strcmp(ATTR(attrs, type), STR_TYPE_LINK) && ATTR_MASK_TEST(attrs, link)) /* display: id, type, mode, nlink, (status,) owner, group, size, mtime, path -> link */ printf(DFID" %-4s %s %3u "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s -> %s\n", PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL, uname, gname, ATTR(attrs, size), date_str, id->fullname, ATTR(attrs,link)); else /* display all: id, type, mode, nlink, (status,) owner, group, size, mtime, path */ printf(DFID" %-4s %s %3u "STATUS_FORMAT"%-10s %-10s %15"PRIu64" %20s %s\n", PFID(&id->id), type, mode_str, ATTR(attrs, nlink) STATUS_VAL, uname, gname, ATTR(attrs, size), date_str, id->fullname); } else if (prog_options.lsstat) { /* In the worst case scenario, each character will be escaped * to '\xXX'; so the string can be up to 4 time the name * length. */ char escaped_name[4*RBH_NAME_MAX+1]; /* Exclude any file with an uncomplete attributes. */ if ((attrs->attr_mask & LSSTAT_MASK) == LSSTAT_MASK) { printf("[%s,%u,%u,%zu,%lu,%lu,%lu]=%s\n", ATTR(attrs, type), ATTR(attrs, uid), ATTR(attrs, gid), ATTR(attrs, size), ATTR(attrs, ctime), ATTR(attrs, mtime), ATTR(attrs, atime), escape_name(id->fullname, escaped_name)); } else { printf("SKIPPED(%x,%x)=%s\n", attrs->attr_mask, LSSTAT_MASK, id->fullname); } } #ifdef _LUSTRE else if (prog_options.lsost) { char tmpbuf[24576]; FormatStripeList( tmpbuf, sizeof(tmpbuf)-1, &ATTR( attrs, stripe_items), FALSE); printf("%s\t%s\n", id->fullname, tmpbuf); } #endif else { /* just display name */ if (id->fullname) printf("%s\n", id->fullname); else printf(DFID"\n", PFID(&id->id)); } }
int main(int argc, char **argv) { unsigned int i; uid_t u; gid_t g; unsigned int c; struct timeval tinit, tcurr, tdiff, tlast = {0}; struct timeval tref_u, tref_g = {0}; float ratio; InitUidGid_Cache(); printf("Reference test of getpwuid (%u items)\n", MAX_UID); gettimeofday(&tinit, NULL); for (i = 0; i <= MAX_UID/10; i++) for (u = 0; u < 10; u++) getpwuid(u); gettimeofday(&tcurr, NULL); timersub(&tcurr, &tinit, &tdiff); tref_u = tdiff; printf("Elapsed time: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_UID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); printf("\nReference test of getgrgid (%u items)\n", MAX_GID); gettimeofday(&tinit, NULL); for (i = 0; i <= MAX_GID/10; i++) for (u = 0; u < 10; u++) getgrgid(u); gettimeofday(&tcurr, NULL); timersub(&tcurr, &tinit, &tdiff); tref_g = tdiff; printf("Elapsed time: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_GID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); printf("\nTest of password cache\n"); gettimeofday(&tinit, NULL); for (i = 0; i <= 10; i++) { c = 0; for (u = 0; u < MAX_UID; u++) { const struct passwd *ppw; ppw = GetPwUid(u); if (ppw) c++; } gettimeofday(&tcurr, NULL); timersub(&tcurr, &tinit, &tdiff); if (i == 0) tlast = tdiff; printf("loop %u, %u items: %lu.%06lu\n", i, c, tdiff.tv_sec, tdiff.tv_usec); if (i == 0) { printf(" Insertion rate: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_UID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); } else if (i == 1) { printf(" Elapsed time: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_UID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); ratio = (tlast.tv_sec*1000000.0 + tlast.tv_usec)/(tdiff.tv_sec*1000000.0 + tdiff.tv_usec); printf(" SPEED-UP (vs insert): x%.2f\n", ratio); ratio = (tref_u.tv_sec*1000000.0 + tref_u.tv_usec)/(tdiff.tv_sec*1000000.0 + tdiff.tv_usec); printf(" SPEED-UP (vs ref): x%.2f\n", ratio); } tinit = tcurr; } /* Now, check that the values returned are correct */ for (u = 0; u < MAX_UID; u++) { const struct passwd *ppw; char buf[50]; ppw = GetPwUid(u); assert(ppw != NULL); assert(ppw->pw_uid == u); sprintf(buf, "%ld", (long)u); assert(strcmp(ppw->pw_name, buf) == 0); } assert(GetPwUid(MAX_UID) == NULL); printf("\nTest of group cache\n"); gettimeofday(&tinit, NULL); for (i = 0; i <= 10; i++) { c = 0; for (g = 0; g < MAX_GID; g++) { const struct group *pgr; pgr = GetGrGid(g); if (pgr) c++; } gettimeofday(&tcurr, NULL); timersub(&tcurr, &tinit, &tdiff); if (i == 0) tlast = tdiff; printf("loop %u, %u items: %lu.%06lu\n", i, c, tdiff.tv_sec, tdiff.tv_usec); if (i == 0) { printf(" Insertion rate: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_GID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); } else if (i == 1) { /* compute speedup */ ratio = (tlast.tv_sec*1000000.0 + tlast.tv_usec)/(tdiff.tv_sec*1000000.0 + tdiff.tv_usec); printf(" SPEED-UP (vs insert): x%.2f\n", ratio); ratio = (tref_g.tv_sec*1000000.0 + tref_g.tv_usec)/(tdiff.tv_sec*1000000.0 + tdiff.tv_usec); printf(" SPEED-UP (vs ref): x%.2f\n", ratio); printf(" Elapsed time: %ld.%06ld (%.1f/s)\n", tdiff.tv_sec, tdiff.tv_usec, MAX_GID / (tdiff.tv_sec + tdiff.tv_usec/1000000.0)); } tinit = tcurr; } /* Now, check that the values returned are correct */ for (g = 0; g < MAX_GID; g++) { const struct group *pgr; char buf[50]; pgr = GetGrGid(g); assert(pgr != NULL); assert(pgr->gr_gid == g); sprintf(buf, "%ld", (long)g); assert(strcmp(pgr->gr_name, buf) == 0); } assert(GetGrGid(MAX_GID) == NULL); printf("Stats:\n"); printf(" password cache hit=%d, miss=%d\n", pw_nb_get, pw_nb_set); printf(" group cache hit=%d, miss=%d\n", gr_nb_get, gr_nb_set); assert(pw_nb_get == 11 * MAX_UID); assert(pw_nb_set == MAX_UID); assert(gr_nb_get == 11 * MAX_GID); assert(gr_nb_set == MAX_GID); return 0; }