Yet another ping... 3 months and counting -- has this gotten lost? By now the patch might need slight forward porting, but the functionality won't change at all, so please let me know if it's worthwhile to spend time on that. Igor
On Thu, 1 May 2003, Igor Pechtchanski wrote: > 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 <[EMAIL PROTECTED]> > > * cygcheck.cc (pretty_id): Parse id output without > using strtok. > (match_paren): New static function. -- http://cs.nyu.edu/~pechtcha/ |\ _,,,---,,_ [EMAIL PROTECTED] ZZZzz /,`.-'`' -. ;-;;,_ [EMAIL PROTECTED] |,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski, Ph.D. '---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow! "I have since come to realize that being between your mentor and his route to the bathroom is a major career booster." -- Patrick Naughton
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++)