[PATCH] cygcheck parsing of id output
Igor Pechtchanski
pechtcha@cs.nyu.edu
Thu May 1 22:50:00 GMT 2003
Hi,
The attached patch allows cygcheck to handle spaces, commas, and
*matching* parentheses in user and group names in the "id" output.
There's some code sharing in parsing the user and group names, but that
could be refactored in a later cleanup.
One issue that also came up is the old "run a cygwin program from a
non-cygwin program from an xterm" issue -- when running cygcheck from an
xterm, id pops up a separate window and cygcheck gets no output from id...
I'm not sure how to fix this. One thing that comes to mind is making
cygcheck aware of Cygwin ptys, but I don't know how hard that would be...
Igor
==============================================================================
ChangeLog:
2003-05-01 Igor Pechtchanski <pechtcha@cs.nyu.edu>
* cygcheck.cc (pretty_id): Parse id output without
using strtok.
(match_paren): New static function.
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ pechtcha@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ igor@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!
Knowledge is an unending adventure at the edge of uncertainty.
-- Leto II
-------------- next part --------------
Index: cygcheck.cc
===================================================================
RCS file: /cvs/src/src/winsup/utils/cygcheck.cc,v
retrieving revision 1.34
diff -u -p -r1.34 cygcheck.cc
--- cygcheck.cc 26 Apr 2003 21:52:03 -0000 1.34
+++ cygcheck.cc 1 May 2003 22:35:17 -0000
@@ -761,6 +761,22 @@ scan_registry (RegInfo * prev, HKEY hKey
free (subkey_name);
}
+/* If *str=='(', returns a pointer to matching parenthesis or NULL if none. */
+static char *match_paren(char *str)
+{
+ char *p = str;
+ int pcount = 1;
+ if (*p != '(') return NULL;
+ for (p++; *p; p++)
+ {
+ if (*p == '(') pcount++;
+ if (*p == ')') pcount--;
+ if (pcount == 0) break;
+ }
+ if (!*p) return NULL;
+ return p;
+}
+
void
pretty_id (const char *s, char *cygwin, size_t cyglen)
{
@@ -784,20 +800,91 @@ pretty_id (const char *s, char *cygwin,
char buf[16384];
fgets (buf, sizeof (buf), f);
- char *uid = strtok (buf, " ") + sizeof ("uid=") - 1;
- char *gid = strtok (NULL, " ") + sizeof ("gid=") - 1;
+ if (!*buf)
+ {
+ printf("Unable to parse id output: no output\n");
+ return;
+ }
+ char *uid = buf;
+ char *p = uid + sizeof("uid=") - 1;
+ if (strncmp(uid, "uid=", p - uid) || !isdigit(*p))
+ {
+ printf("Unable to parse id output: no uid= part; full output is\n%s\n", uid);
+ return;
+ }
+ uid = p;
+ for (; *p && isdigit(*p); p++)
+ ;
+ if (*p != '(')
+ {
+ printf("Unable to parse id output: no uid name; full output is\n%s\n", uid);
+ return;
+ }
+ p = match_paren(p);
+ if (p == NULL || *++p != ' ')
+ {
+ printf("Unable to parse id output: uid name parens unmatched; full output is\n%s\n", uid);
+ return;
+ }
+ *p++ = '\0';
+ char *gid = p;
+ p = gid + sizeof("gid=") - 1;
+ if (strncmp(gid, "gid=", p - gid) || !isdigit(*p))
+ {
+ printf("Unable to parse id output: no gid= part; full output is\n%s %s\n", uid, gid);
+ return;
+ }
+ gid = p;
+ for (; *p && isdigit(*p); p++)
+ ;
+ if (*p != '(')
+ {
+ printf("Unable to parse id output: no gid name; full output is\n%s %s\n", uid, gid);
+ return;
+ }
+ p = match_paren(p);
+ if (p == NULL || *++p != ' ')
+ {
+ printf("Unable to parse id output: gid name parens unmatched; full output is\n%s %s\n", uid, gid);
+ return;
+ }
+ *p++ = '\0';
+ char *grp = p;
+ p = grp + sizeof("groups=") - 1;
+ if (strncmp(grp, "groups=", p - grp) || !isdigit(*p))
+ {
+ printf("Unable to parse id output: no groups= part; full output is\n%s %s %s\n", uid, gid, grp);
+ return;
+ }
char **ng;
size_t sz = 0;
- for (ng = groups; (*ng = strtok (NULL, ",")); ng++)
+ for (ng = groups; isdigit(*p); ng++)
{
- char *p = strchr (*ng, '\n');
- if (p)
- *p = '\0';
- if (ng == groups)
- *ng += sizeof ("groups=") - 1;
- size_t len = strlen (*ng);
+ *ng = p;
+ for (; *p && isdigit(*p); p++)
+ ;
+ if (*p != '(')
+ {
+ printf("Unable to parse id output: no group name: %s; full output is\n%s %s %s", ng, uid, gid, grp);
+ for (char **g = groups; g != ng; g++)
+ printf("%s,", g);
+ printf("%s\n", ng);
+ return;
+ }
+ p = match_paren(p);
+ if (p == NULL || (*++p != ',' && *p != '\n' && *p))
+ {
+ printf("Unable to parse id output: group name paren unmatched: %s; full output is\n%s %s %s", ng, uid, gid, grp);
+ for (char **g = groups; g != ng; g++)
+ printf("%s,", g);
+ printf("%s\n", ng);
+ return;
+ }
+ size_t len = p - *ng;
if (sz < len)
sz = len;
+ if (*p)
+ *p++ = '\0';
}
printf ("\n%s output (%s)\n", id, s);
@@ -807,7 +894,6 @@ pretty_id (const char *s, char *cygwin,
sz += 1;
int n = 80 / (int) sz;
sz = -sz;
- ng[0] += sizeof ("groups=") - 1;
printf ("UID: %*s GID: %s\n", sz + (sizeof ("UID: ") - 1), uid, gid);
int i = 0;
for (char **g = groups; g < ng; g++)
More information about the Cygwin-patches
mailing list