Group file in unix contains all groups information in this operating system.
/etc/group:
ubuntu@ip-172-31-23-227:~$ ls -lrt /etc/group
-rw-r--r-- 1 root root 701 Aug 2 14:29 /etc/group
ubuntu@ip-172-31-23-227:~$ less /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,ubuntu
......
1) 1st field: group name
2) 2nd field: encrypted group password
3) 3rd field: group id
4) 4th field: user list, which means who belong to this group.
2. System calls to handle group file in unix programming
Note: gr_mem is an array of string(user name), and this array is terminated by null pointer, normally in programming, we need to detect the null pointer to know the end of array.
ubuntu@ip-172-31-23-227:~$ less /usr/include/grp.h
......
/* The group structure. */
struct group
{
char *gr_name; /* Group name. */
char *gr_passwd; /* Password. */
__gid_t gr_gid; /* Group ID. */
char **gr_mem; /* Member list. */
};
......
/* Rewind the group-file stream.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern void setgrent (void);
......
/* Close the group-file stream.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern void endgrent (void);
/* Read an entry from the group-file stream, opening it if necessary.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct group *getgrent (void);
......
/* Search for an entry with a matching group ID.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct group *getgrgid (__gid_t __gid);
/* Search for an entry with a matching group name.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct group *getgrnam (const char *__name);
......
3. Example:
fileio.c:
#include<stdio.h>
#include<stdlib.h>
#include<grp.h>
void printGrp(struct group *pg)
{
printf("struct address: %p ", pg);
printf("%s:%s:%d:", pg->gr_name, pg->gr_passwd, pg->gr_gid);
char **pc = pg->gr_mem;
// After the last user name is read(or there is no user name),
// the char pointer pc points to is NULL, note: pc is never NULL.
while(*pc != NULL) {
if(pc != pg->gr_mem) printf(",");
printf("%s", *pc);
pc++;
}
printf("\n");
}
int main(int argc, char* argv[])
{
struct group *pg;
// getgrgid example
if((pg = getgrgid(0)) == NULL) {
printf("getgrgid error!\n");
exit(1);
}
printGrp(pg);
// getgrnam example
if((pg = getgrnam("adm")) == NULL) {
printf("getgrnam error!\n");
exit(2);
}
// Itereate group entries
printf("Iterate each group entry: \n");
setgrent();
while((pg = getgrent()) != NULL) {
printGrp(pg);
}
endgrent();
printGrp(pg);
exit(0);
}
shell:
Run the program, it will firstly output the group entry with gid 0, and then output the group entry with name "adm". Note that the struct addresses are same, so it indicate that getgrgid, and getgrnam just overwrite the information at the same place, instead of creating new struct grp.
And then it will iterate each entry in group file, also struct addresses are same.
ubuntu@ip-172-31-23-227:~$ ./io.out
struct address: 0x7f2a09f1b0a0 root:x:0:
struct address: 0x7f2a09f1b0e0 adm:x:4:syslog,ubuntu
Iterate each group entry:
struct address: 0x7f2a09f1b060 root:x:0:
struct address: 0x7f2a09f1b060 daemon:x:1:
struct address: 0x7f2a09f1b060 bin:x:2:
struct address: 0x7f2a09f1b060 sys:x:3:
struct address: 0x7f2a09f1b060 adm:x:4:syslog,ubuntu
No comments:
Post a Comment