Add some tests.
[gnupg.git] / tests / asschk.c
index 7b73216..176fcac 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /* This is a simple stand-alone Assuan server test program.  We don't
@@ -30,8 +29,8 @@
    a line is processed but after comment processing.  Macros are only
    expanded once and non existing macros expand to the empty string.
    A macro is dereferenced by prefixing its name with a dollar sign;
-   the end of the name is currently indicated by a white space.  To
-   use a dollor sign verbatim, double it. 
+   the end of the name is currently indicated by a white space, a
+   dollar sign or a slash.  To use a dollor sign verbatim, double it.
 
    A macro is assigned by prefixing a statement with the macro name
    and an equal sign.  The value is assigned verbatim if it does not
       Print VALUE.
 
    openfile <filename>
-      Open file FILENAME for read access and retrun the file descriptor.
+      Open file FILENAME for read access and return the file descriptor.
 
    createfile <filename>
-      Create file FILENAME, open for write access and retrun the file
+      Create file FILENAME, open for write access and return the file
       descriptor.
 
    pipeserver <program>
@@ -96,6 +95,9 @@
    cmpfiles <first> <second>
       Returns true when the content of the files FIRST and SECOND match.
 
+   getenv <name>
+      Return the value of the environment variable NAME.
+
 */
 
 #include <stdio.h>
 # define ATTR_PRINTF(f,a)
 #endif
 
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+#  define __func__ __FUNCTION__
+# else
+/* Let's try our luck here.  Some systems may provide __func__ without
+   providing __STDC_VERSION__ 199901L.  */
+#  if 0
+#   define __func__ "<unknown>"
+#  endif
+# endif
+#endif
+
 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
 
 #define MAX_LINELEN 2048
@@ -185,6 +199,8 @@ die (const char *format, ...)
   exit (1);
 }
 
+#define die(format, args...) (die) ("%s: " format, __func__ , ##args)
+
 static void
 err (const char *format, ...)
 {
@@ -255,16 +271,17 @@ writen (int fd, const char *buffer, size_t length)
    type and store that in recv_type.  The function terminates on a
    communication error.  Returns a pointer into the inputline to the
    first byte of the arguments.  The parsing is very strict to match
-   excalty what we want to send. */
+   exaclty what we want to send. */
 static char *
 read_assuan (int fd)
 {
+  /* FIXME: For general robustness, the pending stuff needs to be
+     associated with FD.  */
   static char pending[MAX_LINELEN];
   static size_t pending_len;
   size_t nleft = sizeof recv_line;
   char *buf = recv_line;
   char *p;
-  int nread = 0;
 
   while (nleft > 0)
     {
@@ -279,19 +296,31 @@ read_assuan (int fd)
           pending_len = 0;
         }
       else
-        n = read (fd, buf, nleft);
-      if (n < 0)
         {
-          if (errno == EINTR)
-            continue;
-          die ("reading fd %d failed: %s", fd, strerror (errno));
+          do
+            {
+              n = read (fd, buf, nleft);
+            }
+          while (n < 0 && errno == EINTR);
         }
+      
+      if (opt_verbose && n >= 0 )
+       {
+         int i;
+
+         printf ("%s: read \"", __func__);
+         for (i = 0; i < n; i ++)
+           putc (buf[i], stdout);
+         printf ("\"\n");
+       }
+
+      if (n < 0)
+        die ("reading fd %d failed: %s", fd, strerror (errno));
       else if (!n)
         die ("received incomplete line on fd %d", fd);
       p = buf;
       nleft -= n;
       buf += n;
-      nread += n;
       
       for (; n && *p != '\n'; n--, p++)
         ;
@@ -300,16 +329,15 @@ read_assuan (int fd)
           if (n>1)
             {
               n--;
-              memcpy (pending, p+1, n);
+              memcpy (pending, p + 1, n);
               pending_len = n;
             }
+         *p = '\0';
           break;
         }
     }
   if (!nleft)
     die ("received line too large");
-  assert (nread>0);
-  recv_line[nread-1] = 0;
 
   p = recv_line;
   if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2]))
@@ -359,7 +387,8 @@ write_assuan (int fd, const char *line)
     buffer[n++] = '\n';
 
   if (writen (fd, buffer, n))
-      die ("sending line to %d failed: %s", fd, strerror (errno));
+      die ("sending line (\"%s\") to %d failed: %s", buffer, fd,
+          strerror (errno));
 }
 
 
@@ -417,6 +446,8 @@ start_server (const char *pgmname)
          close (fd);
         }
 
+      close (wp[1]);
+      close (rp[0]);
       execl (pgmname, arg0, "--server", NULL); 
       die ("exec failed for `%s': %s", pgmname, strerror (errno));
     }
@@ -571,7 +602,8 @@ expand_line (char *buffer)
           line = p + 1;
           continue;
         }
-      for (pend=p+1; *pend && !spacep (pend) && *pend != '$'; pend++)
+      for (pend=p+1; *pend && !spacep (pend)
+           && *pend != '$' && *pend != '/'; pend++)
         ;
       if (*pend)
         {
@@ -854,6 +886,17 @@ cmd_cmpfiles (const char *assign_to, char *arg)
   fclose (fp2);
 }
 
+static void
+cmd_getenv (const char *assign_to, char *arg)
+{
+  const char *s;
+  s = *arg? getenv (arg):"";
+  set_var (assign_to, s? s:"");
+}
+
+
+
+\f
 /* Process the current script line LINE. */
 static int
 interpreter (char *line)
@@ -875,6 +918,7 @@ interpreter (char *line)
     { "quit-if"   , cmd_quit_if },
     { "fail-if"   , cmd_fail_if },
     { "cmpfiles"  , cmd_cmpfiles },
+    { "getenv"    , cmd_getenv },
     { NULL }
   };
   char *p, *save_p;