This is MiscUserGroup.m in view mode; [Download] [Up]
/**************************************************************************** CLASS: MiscUserGroup See the interface file for more information. Copyright (c) 1995 by author. All rights reserved. Usage is governed by the MiscKit license. *****************************************************************************/ #import <sys/types.h> #import <pwd.h> #import <grp.h> #import <appkit/nextstd.h> #import <objc/List.h> #import <misckit/MiscListExtensions.h> #import <objc/HashTable.h> #import <misckit/MiscUser.h> #import <misckit/MiscUserGroup.h> @implementation MiscUserGroup + (List *)allGroups; { // Returns a List containing all the MiscUserGroups on the system. You are // responsible for freeing both the returned List and contents. All domains // will be traversed and duplicates are removed. List *groupList = nil; MiscUserGroup *aGroup; struct group *gr; setgrent(); do { gr = getgrent(); if (gr != NULL) { if (groupList == nil) groupList = [ [List alloc] init]; // Check to see if the group name is already in the list, // since the same group can be in multiple domains. if ([groupList matchString: gr->gr_name usingSel: @selector(groupName)] == NO) { aGroup = [ [self alloc] initWithGroupId: gr->gr_gid]; [groupList addObject: aGroup]; } } } while (gr != NULL); endgrent(); return groupList; } - initWithGroupId: (int)groupId { // The designated initializer. If the gid does not exist, nil is // returned and the receiver is freed. struct group *gr; [super init]; gr = getgrgid (groupId); if (gr == NULL) { [super free]; return nil; } gid = groupId; NX_MALLOC (groupname, char, strlen (gr->gr_name)+1); strcpy (groupname, gr->gr_name); return self; } - initWithGroupName: (const char *)gname { struct group *gr; if (gname == NULL) return nil; // Docs say (takes const char *, but actually only for POSIX. gr = getgrnam ((char *)gname); if (gr == NULL) { [super free]; return nil; } return [self initWithGroupId: gr->gr_gid]; } - free { if (groupname != NULL) NX_FREE (groupname); return [super free]; } - (const char *)groupName { return groupname; } - (int)groupId { return gid; } - (List *)members { // Returns a list of MiscUser objects representing all the members // of the receiver. You are responsible for freeing the List and contents. // Since there is a possibility of crossing multiple domains with // duplicated groups names, we have to step through the entire list of // groups and merge all the members into the returned list. List *userList = nil; MiscUser *aUser; struct group *gr; int i; setgrent(); do { gr = getgrent(); if (gr == NULL) break; if (gr->gr_gid == [self groupId]) { if (*(gr->gr_mem) == NULL) continue; if (userList == nil) userList = [ [List alloc] init]; for (i=0; gr->gr_mem[i]!=NULL; ++i) // Check if the user is already on the list. if ([userList matchString: gr->gr_mem[i] usingSel: @selector (username)] == NO) { aUser = [ [MiscUser alloc] initWithUsername: gr->gr_mem[i] ]; [userList addObject: aUser]; } } } while (gr != NULL); return userList; } @end /*************************************************************************** CHANGES January 23, 1995 Version 0.2 (todd) 1. Upon testing on a machine with two domains (local and network) I found that the UNIX functions I am using will return duplicates if groups exist in both domains. I therefore added some code to remove duplicates, and in some cases go through the entire list of groups to merge all relevant information from each domain (when looking for members). ****************************************************************************/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.