[PATCH] cygcheck parsing of id output

Igor Pechtchanski pechtcha@cs.nyu.edu
Thu Aug 7 15:36:00 GMT 2003


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  <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, 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
-------------- 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