getgrent.c

Go to the documentation of this file.
00001 /*      getgrent(), getgrgid(), getgrnam() - group file routines
00002  *
00003  *                                                      Author: Kees J. Bot
00004  *                                                              31 Jan 1994
00005  */
00006 #define nil 0
00007 #define open _open
00008 #define fcntl _fcntl
00009 #define read _read
00010 #define close _close
00011 #include <sys/types.h>
00012 #include <grp.h>
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <unistd.h>
00016 #include <fcntl.h>
00017 
00018 #define arraysize(a)    (sizeof(a) / sizeof((a)[0]))
00019 #define arraylimit(a)   ((a) + arraysize(a))
00020 
00021 static char GROUP[]= "/etc/group";      /* The group file. */
00022 static const char *grfile;              /* Current group file. */
00023 
00024 static char buf[1024];                  /* Read buffer. */
00025 static char grline[512];                /* One line from the group file. */
00026 static struct group entry;              /* Entry to fill and return. */
00027 static char *members[64];               /* Group members with the entry. */
00028 static int grfd= -1;                    /* Filedescriptor to the file. */
00029 static char *bufptr;                    /* Place in buf. */
00030 static ssize_t buflen= 0;               /* Remaining characters in buf. */
00031 static char *lineptr;                   /* Place in the line. */
00032 
00033 void endgrent(void)
00034 /* Close the group file. */
00035 {
00036         if (grfd >= 0) {
00037                 (void) close(grfd);
00038                 grfd= -1;
00039                 buflen= 0;
00040         }
00041 }
00042 
00043 int setgrent(void)
00044 /* Open the group file. */
00045 {
00046         if (grfd >= 0) endgrent();
00047 
00048         if (grfile == nil) grfile= GROUP;
00049 
00050         if ((grfd= open(grfile, O_RDONLY)) < 0) return -1;
00051         (void) fcntl(grfd, F_SETFD, fcntl(grfd, F_GETFD) | FD_CLOEXEC);
00052         return 0;
00053 }
00054 
00055 void setgrfile(const char *file)
00056 /* Prepare for reading an alternate group file. */
00057 {
00058         endgrent();
00059         grfile= file;
00060 }
00061 
00062 static int getline(void)
00063 /* Get one line from the group file, return 0 if bad or EOF. */
00064 {
00065         lineptr= grline;
00066 
00067         do {
00068                 if (buflen == 0) {
00069                         if ((buflen= read(grfd, buf, sizeof(buf))) <= 0)
00070                                 return 0;
00071                         bufptr= buf;
00072                 }
00073 
00074                 if (lineptr == arraylimit(grline)) return 0;
00075                 buflen--;
00076         } while ((*lineptr++ = *bufptr++) != '\n');
00077 
00078         lineptr= grline;
00079         return 1;
00080 }
00081 
00082 static char *scan_punct(int punct)
00083 /* Scan for a field separator in a line, return the start of the field. */
00084 {
00085         char *field= lineptr;
00086         char *last;
00087 
00088         for (;;) {
00089                 last= lineptr;
00090                 if (*lineptr == 0) return nil;
00091                 if (*lineptr == '\n') break;
00092                 if (*lineptr++ == punct) break;
00093                 if (lineptr[-1] == ':') return nil;     /* :::,,,:,,,? */
00094         }
00095         *last= 0;
00096         return field;
00097 }
00098 
00099 struct group *getgrent(void)
00100 /* Read one entry from the group file. */
00101 {
00102         char *p;
00103         char **mem;
00104 
00105         /* Open the file if not yet open. */
00106         if (grfd < 0 && setgrent() < 0) return nil;
00107 
00108         /* Until a good line is read. */
00109         for (;;) {
00110                 if (!getline()) return nil;     /* EOF or corrupt. */
00111 
00112                 if ((entry.gr_name= scan_punct(':')) == nil) continue;
00113                 if ((entry.gr_passwd= scan_punct(':')) == nil) continue;
00114                 if ((p= scan_punct(':')) == nil) continue;
00115                 entry.gr_gid= strtol(p, nil, 0);
00116 
00117                 entry.gr_mem= mem= members;
00118                 if (*lineptr != '\n') {
00119                         do {
00120                                 if ((*mem= scan_punct(',')) == nil) goto again;
00121                                 if (mem < arraylimit(members) - 1) mem++;
00122                         } while (*lineptr != 0);
00123                 }
00124                 *mem= nil;
00125                 return &entry;
00126         again:;
00127         }
00128 }
00129 
00130 struct group *getgrgid(_mnx_Gid_t gid)
00131 /* Return the group file entry belonging to the user-id. */
00132 {
00133         struct group *gr;
00134 
00135         endgrent();
00136         while ((gr= getgrent()) != nil && gr->gr_gid != gid) {}
00137         endgrent();
00138         return gr;
00139 }
00140 
00141 struct group *getgrnam(const char *name)
00142 /* Return the group file entry belonging to the user name. */
00143 {
00144         struct group *gr;
00145 
00146         endgrent();
00147         while ((gr= getgrent()) != nil && strcmp(gr->gr_name, name) != 0) {}
00148         endgrent();
00149         return gr;
00150 }

Generated on Fri Apr 14 22:57:26 2006 for minix by  doxygen 1.4.6