+ char * s = strdup(str);
+ char * f = s;
+ const char * file = NULL;
+ char * eol;
+
+ sp->uid = sp->gid = sp->umask = -1;
+
+ if ((eol = strchr(s, ',')))
+ {
+ do
+ {
+ if ((eol = strchr(s, ',')))
+ *eol++ = '\0';
+ if (sp->uid == -1 && strncmp(s, "user=", 5) == 0)
+ {
+ char * arg = s + 5;
+ if (strspn(arg, "0123456789") == strlen(arg))
+ {
+ sp->uid = atoi(arg);
+ }
+ else
+ {
+ struct passwd * pw = getpwnam(arg);
+ if(pw == NULL)
+ {
+ printf("No such user\n");
+ free(f);
+ return 0;
+ }
+ sp->uid = pw->pw_uid;
+ }
+ }
+ else if (sp->gid == -1 && strncmp(s, "group=", 6) == 0)
+ {
+ char * arg = s + 6;
+ if (strspn(arg, "0123456789") == strlen(arg))
+ {
+ sp->gid = atoi(arg);
+ }
+ else
+ {
+ struct group * gr = getgrnam(arg);
+ if (gr == NULL)
+ {
+ printf("No such group\n");
+ free(f);
+ return 0;
+ }
+ sp->gid = gr->gr_gid;
+ }
+ }
+ else if (sp->umask == -1 && strncmp(s, "umask=", 6) == 0)
+ {
+ char * end;
+ char * arg = s + 6;
+
+ sp->umask = strtol(arg, &end, 8);
+ if (errno == EINVAL ||
+ *end)
+ {
+ printf("Invalid umask\n");
+ free(f);
+ return 0;
+ }
+ }
+ else if (file == NULL && strncmp(s, "file=", 5) == 0)
+ {
+ char * arg = s + 5;
+ file = arg;
+ }
+ else
+ {
+ printf("invalid or double argument: %s\n", s);
+ free(f);
+ return 0;
+ }
+ } while((s = eol));
+ }
+ else
+ {
+ file = str;
+ }
+ if(! file)
+ {
+ errno = EINVAL;
+ return 0;
+ }