+ char *g, *u, *separator;
+ char *groupname;
+ int maybe_retry = 0;
+ char *dot = NULL;
+
+ error_msg = NULL;
+ *username_arg = *groupname_arg = NULL;
+ groupname = NULL;
+
+ V_STRDUP (spec, spec_arg);
+
+ /* Find the POSIX `:' separator if there is one. */
+ separator = strchr (spec, ':');
+
+ /* If there is no colon, then see if there's a `.'. */
+ if (separator == NULL)
+ {
+ dot = strchr (spec, '.');
+ /* If there's no colon but there is a `.', then first look up the
+ whole spec, in case it's an OWNER name that includes a dot.
+ If that fails, then we'll try again, but interpreting the `.'
+ as a separator. */
+ /* FIXME: accepting `.' as the separator is contrary to POSIX.
+ someday we should drop support for this. */
+ if (dot)
+ maybe_retry = 1;
+ }
+
+ retry:
+
+ /* Replace separator with a NUL. */
+ if (separator != NULL)
+ *separator = '\0';
+
+ /* Set U and G to non-zero length strings corresponding to user and
+ group specifiers or to NULL. */
+ u = (*spec == '\0' ? NULL : spec);
+
+ g = (separator == NULL || *(separator + 1) == '\0'
+ ? NULL
+ : separator + 1);
+
+ if (u == NULL && g == NULL)
+ return _(E_cannot_omit_both);