| 91 | Otherwise return zero. */ |
| 92 | |
| 93 | static int |
| 94 | parse_additional_groups (char const *groups, GETGROUPS_T **pgids, |
| 95 | idx_t *pn_gids, bool show_errors) |
| 96 | { |
| 97 | GETGROUPS_T *gids = NULL; |
| 98 | idx_t n_gids_allocated = 0; |
| 99 | idx_t n_gids = 0; |
| 100 | char *buffer = xstrdup (groups); |
| 101 | int ret = 0; |
| 102 | |
| 103 | for (char const *tmp = strtok (buffer, ","); tmp; |
| 104 | tmp = strtok (NULL, ",")) |
| 105 | { |
| 106 | struct group *g; |
| 107 | uintmax_t value; |
| 108 | |
| 109 | if (xstrtoumax (tmp, NULL, 10, &value, "") == LONGINT_OK |
| 110 | && value <= MAXGID) |
| 111 | { |
| 112 | while (isspace (to_uchar (*tmp))) |
| 113 | tmp++; |
| 114 | if (*tmp != '+') |
| 115 | { |
| 116 | /* Handle the case where the name is numeric. */ |
| 117 | g = getgrnam (tmp); |
| 118 | if (g != NULL) |
| 119 | value = g->gr_gid; |
| 120 | } |
| 121 | /* Flag that we've got a group from the number. */ |
| 122 | g = (struct group *) (intptr_t) ! NULL; |
| 123 | } |
| 124 | else |
| 125 | { |
| 126 | g = getgrnam (tmp); |
| 127 | if (g != NULL) |
| 128 | value = g->gr_gid; |
| 129 | } |
| 130 | |
| 131 | if (g == NULL) |
| 132 | { |
| 133 | ret = -1; |
| 134 | |
| 135 | if (show_errors) |
| 136 | { |
| 137 | error (0, errno, _("invalid group %s"), quote (tmp)); |
| 138 | continue; |
| 139 | } |
| 140 | |
| 141 | break; |
| 142 | } |
| 143 | |
| 144 | if (n_gids == n_gids_allocated) |
| 145 | gids = xpalloc (gids, &n_gids_allocated, 1, -1, sizeof *gids); |
| 146 | gids[n_gids++] = value; |
| 147 | } |
| 148 | |
| 149 | if (ret == 0 && n_gids == 0) |
| 150 | { |