cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH 1/2] Generate lists and use symbols in --libcurl code output.

From: Colin Hogben <curl_at_pythontech.co.uk>
Date: Thu, 22 Dec 2011 13:58:00 +0000

This patch improves the output of curl's --libcurl option by
generating code which builds curl_httppost and curl_slist lists, and
uses symbolic names for enum and flag values. Variants of the
my_setopt macro in tool_operate.c are added in order to pass extra type
information to the code-generation step in tool_setopt.c.

---
 src/tool_easysrc.c |   12 ++
 src/tool_easysrc.h |    2 +
 src/tool_operate.c |   55 ++++---
 src/tool_setopt.c  |  417 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/tool_setopt.h  |   49 ++++++
 5 files changed, 484 insertions(+), 51 deletions(-)
diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c
index 5c42e80..8a65eec 100644
--- a/src/tool_easysrc.c
+++ b/src/tool_easysrc.c
@@ -37,6 +37,8 @@
 
 struct curl_slist *easysrc = NULL;
 struct curl_slist *easysrc_remarks = NULL;
+bool easysrc_form = FALSE;
+int easysrc_slists = 0;
 
 static const char *const srchead[]={
   "/********* Sample code generated by the curl command line tool **********",
@@ -74,12 +76,22 @@ void dumpeasysrc(struct Configurable *config)
       for(i=0; ((c = srchead[i]) != '\0'); i++)
         fprintf(out, "%s\n", c);
 
+      if(easysrc_form)
+        fprintf(out, "  struct curl_httppost *post = NULL, *end = NULL;\n");
+      for(i=0; i<easysrc_slists; i++)
+        fprintf(out, "  struct curl_slist *slist%d = NULL;\n", i);
+
       ptr = easysrc;
       while(ptr) {
         fprintf(out, "  %s\n", ptr->data);
         ptr = ptr->next;
       }
 
+      if(easysrc_form)
+        fprintf(out, "  curl_formfree(post);\n");
+      for(i=0; i<easysrc_slists; i++)
+        fprintf(out, "  curl_slist_free_all(slist%d);\n", i);
+
       ptr = easysrc_remarks;
       if(ptr) {
         fprintf(out,
diff --git a/src/tool_easysrc.h b/src/tool_easysrc.h
index 21b5674..804f9e7 100644
--- a/src/tool_easysrc.h
+++ b/src/tool_easysrc.h
@@ -27,6 +27,8 @@
 
 extern struct curl_slist *easysrc;
 extern struct curl_slist *easysrc_remarks;
+extern bool easysrc_form;       /* TRUE if curl_httppost needed */
+extern int easysrc_slists;      /* Number of curl_slist variables */
 
 void dumpeasysrc(struct Configurable *config);
 
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 1e88120..9573736 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -807,25 +807,29 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
 
           /* new in libcurl 7.5 */
           if(config->proxy)
-            my_setopt(curl, CURLOPT_PROXYTYPE, config->proxyver);
+            my_setopt_enum(curl, CURLOPT_PROXYTYPE, CURLPROXY,
+                           config->proxyver);
 
           /* new in libcurl 7.10 */
           if(config->socksproxy) {
             my_setopt_str(curl, CURLOPT_PROXY, config->socksproxy);
-            my_setopt(curl, CURLOPT_PROXYTYPE, config->socksver);
+            my_setopt_enum(curl, CURLOPT_PROXYTYPE, CURLPROXY,
+                           config->socksver);
           }
 
           /* new in libcurl 7.10.6 */
           if(config->proxyanyauth)
-            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+            my_setopt_flags(curl, CURLOPT_PROXYAUTH, CURLAUTH, CURLAUTH_ANY);
           else if(config->proxynegotiate)
-            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_GSSNEGOTIATE);
+            my_setopt_flags(curl, CURLOPT_PROXYAUTH, CURLAUTH,
+                           CURLAUTH_GSSNEGOTIATE);
           else if(config->proxyntlm)
-            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
+            my_setopt_flags(curl, CURLOPT_PROXYAUTH, CURLAUTH, CURLAUTH_NTLM);
           else if(config->proxydigest)
-            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
+            my_setopt_flags(curl, CURLOPT_PROXYAUTH, CURLAUTH,
+                           CURLAUTH_DIGEST);
           else if(config->proxybasic)
-            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+            my_setopt_flags(curl, CURLOPT_PROXYAUTH, CURLAUTH, CURLAUTH_BASIC);
 
           /* new in libcurl 7.19.4 */
           my_setopt(curl, CURLOPT_NOPROXY, config->noproxy);
@@ -868,7 +872,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
                       config->postfieldsize);
             break;
           case HTTPREQ_POST:
-            my_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
+            my_setopt_httppost(curl, CURLOPT_HTTPPOST, config->httppost);
             break;
           default:
             break;
@@ -877,18 +881,20 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
           my_setopt_str(curl, CURLOPT_REFERER, config->referer);
           my_setopt(curl, CURLOPT_AUTOREFERER, config->autoreferer);
           my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
-          my_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
+          my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
 
           /* new in libcurl 7.5 */
           my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
 
           /* new in libcurl 7.9.1 */
           if(config->httpversion)
-            my_setopt(curl, CURLOPT_HTTP_VERSION, config->httpversion);
+            my_setopt_enum(curl, CURLOPT_HTTP_VERSION,
+                           CURL_HTTP_VERSION, config->httpversion);
 
           /* new in libcurl 7.10.6 (default is Basic) */
           if(config->authtype)
-            my_setopt(curl, CURLOPT_HTTPAUTH, config->authtype);
+            my_setopt_flags(curl, CURLOPT_HTTPAUTH,
+                            CURLAUTH, config->authtype);
 
           /* curl 7.19.1 (the 301 version existed in 7.18.2) */
           my_setopt(curl, CURLOPT_POSTREDIR, config->post301 |
@@ -983,9 +989,9 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
         }
 
         my_setopt(curl, CURLOPT_CRLF, config->crlf);
-        my_setopt(curl, CURLOPT_QUOTE, config->quote);
-        my_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
-        my_setopt(curl, CURLOPT_PREQUOTE, config->prequote);
+        my_setopt_slist(curl, CURLOPT_QUOTE, config->quote);
+        my_setopt_slist(curl, CURLOPT_POSTQUOTE, config->postquote);
+        my_setopt_slist(curl, CURLOPT_PREQUOTE, config->prequote);
 
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
         {
@@ -1006,8 +1012,10 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
         }
 #endif
 
-        my_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
-        my_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
+        my_setopt_enum(curl, CURLOPT_SSLVERSION,
+                       CURL_SSLVERSION, config->ssl_version);
+        my_setopt_enum(curl, CURLOPT_TIMECONDITION,
+                       CURL_TIMECOND, config->timecond);
         my_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
         my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
         my_setopt(curl, CURLOPT_STDERR, config->errors);
@@ -1026,7 +1034,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
         }
 
         /* new in libcurl 7.6.2: */
-        my_setopt(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
+        my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
 
         /* new in libcurl 7.7: */
         my_setopt_str(curl, CURLOPT_RANDOM_FILE, config->random_file);
@@ -1090,7 +1098,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
 
         /* new in curl 7.16.1 */
         if(config->ftp_ssl_ccc)
-          my_setopt(curl, CURLOPT_FTP_SSL_CCC, config->ftp_ssl_ccc_mode);
+          my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC,
+                         CURLFTPSSL_CCC, config->ftp_ssl_ccc_mode);
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
         {
@@ -1154,16 +1163,18 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
           my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from);
 
         if(config->mail_rcpt)
-          my_setopt(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt);
+          my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt);
 
         /* curl 7.20.x */
         if(config->ftp_pret)
           my_setopt(curl, CURLOPT_FTP_USE_PRET, TRUE);
 
         if(config->proto_present)
-          my_setopt(curl, CURLOPT_PROTOCOLS, config->proto);
+          my_setopt_flags(curl, CURLOPT_PROTOCOLS,
+                          CURLPROTO, config->proto);
         if(config->proto_redir_present)
-          my_setopt(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir);
+          my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS,
+                          CURLPROTO, config->proto_redir);
 
         if((urlnode->flags & GETOUT_USEREMOTE)
            && config->content_disposition) {
@@ -1179,7 +1190,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
 
         if(config->resolve)
           /* new in 7.21.3 */
-          my_setopt(curl, CURLOPT_RESOLVE, config->resolve);
+          my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve);
 
         /* new in 7.21.4 */
         if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index b636aab..443dc1f 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -33,43 +33,411 @@
 
 #include "memdebug.h" /* keep this as LAST include */
 
+/* Lookup tables for converting setopt values back to symbols */
+/* For enums, values may be in any order. */
+/* For bit masks, put combinations first, then single bits, */
+/* and finally any "NONE" value. */
+
+#define NV(e) {#e, e}
+#define NVEND {NULL, 0}         /* sentinel to mark end of list */
+
+const NameValue CURLAUTH_namevalues[] = {
+  NV(CURLAUTH_ANY),             /* combination */
+  NV(CURLAUTH_ANYSAFE),         /* combination */
+  NV(CURLAUTH_BASIC),
+  NV(CURLAUTH_DIGEST),
+  NV(CURLAUTH_GSSNEGOTIATE),
+  NV(CURLAUTH_NTLM),
+  NV(CURLAUTH_DIGEST_IE),
+  NV(CURLAUTH_NTLM_WB),
+  NV(CURLAUTH_ONLY),
+  NV(CURLAUTH_NONE),
+  NVEND,
+};
+
+const NameValue CURLPROXY_namevalues[] = {
+  NV(CURLPROXY_HTTP),
+  NV(CURLPROXY_HTTP_1_0),
+  NV(CURLPROXY_SOCKS4),
+  NV(CURLPROXY_SOCKS5),
+  NV(CURLPROXY_SOCKS4A),
+  NV(CURLPROXY_SOCKS5_HOSTNAME),
+  NVEND,
+};
+
+const NameValue CURL_TIMECOND_namevalues[] = {
+  NV(CURL_TIMECOND_IFMODSINCE),
+  NV(CURL_TIMECOND_IFUNMODSINCE),
+  NV(CURL_TIMECOND_LASTMOD),
+  NV(CURL_TIMECOND_NONE),
+  NVEND,
+};
+
+const NameValue CURL_SSLVERSION_namevalues[] = {
+  NV(CURL_SSLVERSION_DEFAULT),
+  NV(CURL_SSLVERSION_TLSv1),
+  NV(CURL_SSLVERSION_SSLv2),
+  NV(CURL_SSLVERSION_SSLv3),
+  NVEND,
+};
+
+const NameValue CURLFTPSSL_CCC_namevalues[] = {
+  NV(CURLFTPSSL_CCC_NONE),
+  NV(CURLFTPSSL_CCC_PASSIVE),
+  NV(CURLFTPSSL_CCC_ACTIVE),
+  NVEND,
+};
+
+const NameValue CURL_HTTP_VERSION_namevalues[] = {
+  NV(CURL_HTTP_VERSION_NONE),
+  NV(CURL_HTTP_VERSION_1_0),
+  NV(CURL_HTTP_VERSION_1_1),
+  NVEND,
+};
+
+/* These mappings essentially triplicated - see
+ * tool_libinfo.c and tool_paramhlp.c */
+const NameValue CURLPROTO_namevalues[] = {
+  NV(CURLPROTO_ALL),            /* combination */
+  NV(CURLPROTO_DICT),
+  NV(CURLPROTO_FILE),
+  NV(CURLPROTO_FTP),
+  NV(CURLPROTO_FTPS),
+  NV(CURLPROTO_GOPHER),
+  NV(CURLPROTO_HTTP),
+  NV(CURLPROTO_HTTPS),
+  NV(CURLPROTO_IMAP),
+  NV(CURLPROTO_IMAPS),
+  NV(CURLPROTO_LDAP),
+  NV(CURLPROTO_LDAPS),
+  NV(CURLPROTO_POP3),
+  NV(CURLPROTO_POP3S),
+  NV(CURLPROTO_RTSP),
+  NV(CURLPROTO_SCP),
+  NV(CURLPROTO_SFTP),
+  NV(CURLPROTO_SMTP),
+  NV(CURLPROTO_SMTPS),
+  NV(CURLPROTO_TELNET),
+  NV(CURLPROTO_TFTP),
+  NVEND,
+};
+
+/* Clean up all source code if we run out of memory */
+static void easysrc_free(void)
+{
+  curl_slist_free_all(easysrc_remarks);
+  curl_slist_free_all(easysrc);
+  easysrc_remarks = NULL;
+  easysrc = NULL;
+}
+
+/* Add a source line to the main code or remarks */
+static CURLcode easysrc_add(struct curl_slist **plist, char *bufp)
+{
+  CURLcode ret = CURLE_OK;
+  struct curl_slist *list =
+    curl_slist_append(*plist, bufp);
+  if(!list) {
+    easysrc_free();
+    ret = CURLE_OUT_OF_MEMORY;
+  }
+  else
+    *plist = list;
+  return ret;
+}
+
+/* Format and add code; jump to nomem on malloc error */
+#define PUT(l,args) do { \
+  char *bufp = curlx_maprintf args; \
+  if(! bufp) { \
+    ret = CURLE_OUT_OF_MEMORY; \
+  } \
+  else { \
+    ret = easysrc_add(l, bufp); \
+    free(bufp); \
+  } \
+  if(ret) \
+    goto nomem; \
+} while(0)
+
+#define CODE0(f) PUT(&easysrc,(f))
+#define CODE1(f,a) PUT(&easysrc,(f,a))
+#define CODE2(f,a,b) PUT(&easysrc,(f,a,b))
+#define CODE3(f,a,b,c) PUT(&easysrc,(f,a,b,c))
+
+#define REM0(f) PUT(&easysrc_remarks,(f))
+#define REM1(f,a) PUT(&easysrc_remarks,(f,a))
+#define REM2(f,a,b) PUT(&easysrc_remarks,(f,a,b))
+
+/* Escape string to C string syntax.  Return NULL if out of memory.
+ * Is this correct for those wacky EBCDIC guys? */
+static char *c_escape(const char *str)
+{
+  size_t len = 0;
+  const char *s;
+  unsigned char c;
+  char *escaped, *e;
+  /* First pass - work out how much space we need */
+  for(s=str; (c=*s) != '\0'; s++) {
+    if(c=='\n' || c=='\r' || c=='\t' || c=='\\' || c=='"') {
+      len += 2;
+    }
+    else if(! isprint(c)) {
+      len += 4;
+    }
+    else
+      len ++;
+  }
+  escaped = malloc(len + 1);
+  if(!escaped)
+    return NULL;
+
+  e = escaped;
+  for(s=str; (c=*s) != '\0'; s++) {
+    if(c=='\n') {
+      strcpy(e, "\\n");
+      e += 2;
+    }
+    else if(c=='\r') {
+      strcpy(e, "\\r");
+      e += 2;
+    }
+    else if(c=='\t') {
+      strcpy(e, "\\t");
+      e += 2;
+    }
+    else if(c=='\\') {
+      strcpy(e, "\\\\");
+      e += 2;
+    }
+    else if(c=='"') {
+      strcpy(e, "\\\"");
+      e += 2;
+    }
+    else if(! isprint(c)) {
+      sprintf(e, "\\%03o", c);
+      e += 4;
+    }
+    else
+      *e++ = c;
+  }
+  *e = '\0';
+  return escaped;
+}
+
+/* setopt wrapper for enum types */
+CURLcode tool_setopt_enum(CURL *curl, struct Configurable *config,
+                          const char *name, CURLoption tag,
+                          const NameValue *nvlist, long lval)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, lval);
+  if(!lval)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+    const NameValue *nv = NULL;
+    for(nv=nvlist; nv->name; nv++) {
+      if(nv->value == lval) break; /* found it */
+    }
+    if(! nv->name) {
+      /* If no definition was found, output an explicit value.
+       * This could happen if new values are defined and used
+       * but the NameValue list is not updated. */
+      CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval);
+    }
+    else {
+      CODE2("curl_easy_setopt(hnd, %s, (long)%s);", name, nv->name);
+    }
+  }
+
+ nomem:
+  return ret;
+}
+
+/* setopt wrapper for bit mask */
+CURLcode tool_setopt_flags(CURL *curl, struct Configurable *config,
+                           const char *name, CURLoption tag,
+                           const NameValue *nvlist, long lval)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, lval);
+  if(!lval)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+    char preamble[80];          /* should accommodate any symbol name */
+    long rest = lval;           /* bits not handled yet */
+    const NameValue *nv = NULL;
+    snprintf(preamble, sizeof(preamble),
+             "curl_easy_setopt(hnd, %s, ", name);
+    for(nv=nvlist; nv->name; nv++) {
+      if((nv->value & ~ rest) == 0) {
+        /* all value flags contained in rest */
+        rest &= ~ nv->value;    /* remove bits handled here */
+        CODE3("%s(long)%s%s",
+              preamble, nv->name, rest ? " |" : ");");
+        if(!rest)
+          break;                /* handled them all */
+        /* replace with all spaces for continuation line */
+        sprintf(preamble, "%*s", strlen(preamble), "");
+      }
+    }
+    /* If any bits have no definition, output an explicit value.
+     * This could happen if new bits are defined and used
+     * but the NameValue list is not updated. */
+    if(rest)
+      CODE2("%s%ldL);", preamble, rest);
+  }
+
+ nomem:
+  return ret;
+}
+
+/* setopt wrapper for CURLOPT_HTTPPOST */
+CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config,
+                              const char *name, CURLoption tag,
+                              struct curl_httppost *post)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, post);
+  if(!post)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    struct curl_httppost *pp, *p;
+    /* Assume only ever one curl_httppost option */
+    easysrc_form = TRUE;
+    for(p=post; p; p=p->next) {
+      CODE0("curl_formadd(&post, &end,");
+      CODE1("             CURLFORM_COPYNAME, \"%s\",", p->name);
+      for(pp=p; pp; pp=pp->more) {
+        /* May be several files uploaded for one name;
+         * these are linked through the 'more' pointer */
+        char *e;
+        e = c_escape(pp->contents);
+        if(!e)
+          goto nomem;
+        if(pp->flags & HTTPPOST_FILENAME) {
+          /* file upload as for -F @filename */
+          CODE1("             CURLFORM_FILE, \"%s\",", e);
+        }
+        else if(pp->flags & HTTPPOST_READFILE) {
+          /* content from file as for -F <filename */
+          CODE1("             CURLFORM_FILECONTENT, \"%s\",", e);
+        }
+        else
+          CODE1("             CURLFORM_COPYCONTENTS, \"%s\",", e);
+        free(e);
+        if(pp->showfilename) {
+          e = c_escape(pp->showfilename);
+          if(!e)
+            goto nomem;
+          CODE1("             CURLFORM_FILENAME, \"%s\",", e);
+          free(e);
+        }
+        if(pp->contenttype) {
+          e = c_escape(pp->contenttype);
+          if(!e)
+            goto nomem;
+          CODE1("             CURLFORM_CONTENTTYPE, \"%s\",", e);
+          free(e);
+        }
+      }
+      CODE0("             CURLFORM_END);");
+    }
+    CODE1("curl_easy_setopt(hnd, %s, post);", name);
+    /* curl_formfree() call is generated in dumpeasysrc */
+  }
+
+ nomem:
+  return ret;
+}
+
+/* setopt wrapper for curl_slist options */
+CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config,
+                           const char *name, CURLoption tag,
+                           struct curl_slist *list)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, list);
+  if(!list)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    struct curl_slist *s;
+    int i;
+    /* May need several slist variables, so invent name */
+    i = easysrc_slists ++;
+    for(s=list; s; s=s->next) {
+      char *e = c_escape(s->data);
+      if(!e)
+        goto nomem;
+      CODE3("slist%d = curl_slist_append(slist%d, \"%s\");", i, i, e);
+      free(e);
+    }
+    CODE2("curl_easy_setopt(hnd, %s, slist%d);", name, i);
+    /* curl_slist_free_all() calls are generated in dumpeasysrc */
+  }
+
+ nomem:
+  return ret;
+}
+
+/* generic setopt wrapper for all other options.
+ * Some type information is encoded in the tag value. */
 CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
                      const char *name, CURLoption tag, ...)
 {
   va_list arg;
-  char *bufp;
-  char value[256];
+  char buf[256];
+  const char *value;
   bool remark = FALSE;
   bool skip = FALSE;
+  bool escape = FALSE;
   CURLcode ret = CURLE_OK;
 
   va_start(arg, tag);
 
   if(tag < CURLOPTTYPE_OBJECTPOINT) {
+    /* Value is expected to be a long */
     long lval = va_arg(arg, long);
-    snprintf(value, sizeof(value), "%ldL", lval);
+    snprintf(buf, sizeof(buf), "%ldL", lval);
+    value = buf;
     ret = curl_easy_setopt(curl, tag, lval);
     if(!lval)
       skip = TRUE;
   }
   else if(tag < CURLOPTTYPE_OFF_T) {
+    /* Value is some sort of object pointer */
     void *pval = va_arg(arg, void *);
-    unsigned char *ptr = (unsigned char *)pval;
 
     /* function pointers are never printable */
     if(tag >= CURLOPTTYPE_FUNCTIONPOINT) {
       if(pval) {
-        strcpy(value, "functionpointer"); /* 'value' fits 256 bytes */
+        value = "functionpointer";
         remark = TRUE;
       }
       else
         skip = TRUE;
     }
 
-    else if(pval && str)
-      snprintf(value, sizeof(value), "\"%s\"", (char *)ptr);
+    else if(pval && str) {
+      value = (char *)pval;
+      escape = TRUE;
+    }
     else if(pval) {
-      strcpy(value, "objectpointer"); /* 'value' fits 256 bytes */
+      value = "objectpointer";
       remark = TRUE;
     }
     else
@@ -79,9 +447,11 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
 
   }
   else {
+    /* Value is expected to be curl_off_t */
     curl_off_t oval = va_arg(arg, curl_off_t);
-    snprintf(value, sizeof(value),
+    snprintf(buf, sizeof(buf),
              "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
+    value = buf;
     ret = curl_easy_setopt(curl, tag, oval);
 
     if(!oval)
@@ -94,32 +464,21 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
     /* we only use this for real if --libcurl was used */
 
     if(remark)
-      bufp = curlx_maprintf("%s set to a %s", name, value);
-    else
-      bufp = curlx_maprintf("curl_easy_setopt(hnd, %s, %s);", name, value);
-
-    if(!bufp)
-      ret = CURLE_OUT_OF_MEMORY;
+      REM2("%s set to a %s", name, value);
     else {
-      struct curl_slist *list =
-        curl_slist_append(remark?easysrc_remarks:easysrc, bufp);
-
-      curl_free(bufp);
-
-      if(!list) {
-        curl_slist_free_all(easysrc_remarks);
-        curl_slist_free_all(easysrc);
-        easysrc_remarks = NULL;
-        easysrc = NULL;
-        ret = CURLE_OUT_OF_MEMORY;
+      if(escape) {
+        char *escaped = c_escape(value);
+        if(!escaped)
+          goto nomem;
+        CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
+        free(escaped);
       }
-      else if(remark)
-        easysrc_remarks = list;
       else
-        easysrc = list;
+        CODE2("curl_easy_setopt(hnd, %s, %s);", name, value);
     }
   }
 
+ nomem:
   return ret;
 }
 
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index d01c9eb..5f2b246 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -23,6 +23,31 @@
  ***************************************************************************/
 #include "setup.h"
 
+typedef struct {
+  const char *name;
+  long value;
+} NameValue;
+
+extern const NameValue CURLAUTH_namevalues[];
+extern const NameValue CURLPROXY_namevalues[];
+extern const NameValue CURL_TIMECOND_namevalues[];
+extern const NameValue CURL_SSLVERSION_namevalues[];
+extern const NameValue CURLFTPSSL_CCC_namevalues[];
+extern const NameValue CURL_HTTP_VERSION_namevalues[];
+extern const NameValue CURLPROTO_namevalues[];
+
+CURLcode tool_setopt_enum(CURL *curl, struct Configurable *config,
+                          const char *name, CURLoption tag,
+                          const NameValue *nv, long lval);
+CURLcode tool_setopt_flags(CURL *curl, struct Configurable *config,
+                           const char *name, CURLoption tag,
+                           const NameValue *nv, long lval);
+CURLcode tool_setopt_httppost(CURL *curl, struct Configurable *config,
+                              const char *name, CURLoption tag,
+                              struct curl_httppost *httppost);
+CURLcode tool_setopt_slist(CURL *curl, struct Configurable *config,
+                           const char *name, CURLoption tag,
+                           struct curl_slist *list);
 CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
                      const char *name, CURLoption tag, ...);
 
@@ -42,6 +67,30 @@ CURLcode tool_setopt(CURL *curl, bool str, struct Configurable *config,
     goto show_error; \
 } WHILE_FALSE
 
+#define my_setopt_enum(x,y,n,z)  do { \
+  res = tool_setopt_enum(x, config, #y, y, n##_namevalues, z); \
+  if(res) \
+    goto show_error; \
+} WHILE_FALSE
+
+#define my_setopt_flags(x,y,n,z)  do { \
+  res = tool_setopt_flags(x, config, #y, y, n##_namevalues, z); \
+  if(res) \
+    goto show_error; \
+} WHILE_FALSE
+
+#define my_setopt_httppost(x,y,z)  do { \
+  res = tool_setopt_httppost(x, config, #y, y, z); \
+  if(res) \
+    goto show_error; \
+} WHILE_FALSE
+
+#define my_setopt_slist(x,y,z)  do { \
+  res = tool_setopt_slist(x, config, #y, y, z); \
+  if(res) \
+    goto show_error; \
+} WHILE_FALSE
+
 #define res_setopt(x,y,z) tool_setopt(x, FALSE, config, #y, y, z)
 
 #define res_setopt_str(x,y,z) tool_setopt(x, TRUE, config, #y, y, z)
-- 
1.6.5.6
--------------080201030400000102030306
Content-Type: text/x-patch;
 name="0002-Add-tests-for-curl-s-libcurl-output.patch"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
 filename="0002-Add-tests-for-curl-s-libcurl-output.patch"
RnJvbSA2NDFjOWFjNjk1MGQ2OWQwNTE1ZjQyMDQ1ZGRkMzNjMzUxYWEzZGExIE1vbiBTZXAg
MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBDb2xpbiBIb2diZW4gPGN1cmxAcHl0aG9udGVjaC5j
by51az4KRGF0ZTogVGh1LCAyMiBEZWMgMjAxMSAxNjoxMToyOCArMDAwMApTdWJqZWN0OiBb
UEFUQ0ggMi8yXSBBZGQgdGVzdHMgZm9yIGN1cmwncyAtLWxpYmN1cmwgb3V0cHV0LgoKVGhl
c2UgdGVzdHMgY2hlY2sgdGhlIG91dHB1dCBvZiB0aGUgLS1saWJjdXJsIG9wdGlvbiBvZiBj
dXJsLAppbmNsdWRpbmcgdGhlIGltcHJvdmVkIG9wdGlvbiBoYW5kbGluZyBhZGRlZCBpbiBh
IHJlbGF0ZWQgcGF0Y2guCi0tLQogdGVzdHMvZGF0YS9NYWtlZmlsZS5hbSB8ICAgIDEgKwog
dGVzdHMvZGF0YS90ZXN0MTQwMCAgICB8ICAgOTIgKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrCiB0ZXN0cy9kYXRhL3Rlc3QxNDAxICAgIHwgIDEwOCArKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKwogdGVzdHMvZGF0YS90ZXN0MTQwMiAgICB8ICAxMDIgKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiB0ZXN0cy9kYXRhL3Rlc3QxNDAzICAg
IHwgICA5NyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogdGVzdHMvZGF0YS90
ZXN0MTQwNCAgICB8ICAxNDYgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrCiB0ZXN0cy9kYXRhL3Rlc3QxNDA1ICAgIHwgIDEyMCArKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysKIHRlc3RzL2RhdGEvdGVzdDE0MDYgICAg
fCAgMTEwICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogdGVzdHMvZGF0
YS90ZXN0MTQwNyAgICB8ICAgOTEgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiA5
IGZpbGVzIGNoYW5nZWQsIDg2NyBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKQogY3Jl
YXRlIG1vZGUgMTAwNjQ0IHRlc3RzL2RhdGEvdGVzdDE0MDAKIGNyZWF0ZSBtb2RlIDEwMDY0
NCB0ZXN0cy9kYXRhL3Rlc3QxNDAxCiBjcmVhdGUgbW9kZSAxMDA2NDQgdGVzdHMvZGF0YS90
ZXN0MTQwMgogY3JlYXRlIG1vZGUgMTAwNjQ0IHRlc3RzL2RhdGEvdGVzdDE0MDMKIGNyZWF0
ZSBtb2RlIDEwMDY0NCB0ZXN0cy9kYXRhL3Rlc3QxNDA0CiBjcmVhdGUgbW9kZSAxMDA2NDQg
dGVzdHMvZGF0YS90ZXN0MTQwNQogY3JlYXRlIG1vZGUgMTAwNjQ0IHRlc3RzL2RhdGEvdGVz
dDE0MDYKIGNyZWF0ZSBtb2RlIDEwMDY0NCB0ZXN0cy9kYXRhL3Rlc3QxNDA3CgpkaWZmIC0t
Z2l0IGEvdGVzdHMvZGF0YS9NYWtlZmlsZS5hbSBiL3Rlc3RzL2RhdGEvTWFrZWZpbGUuYW0K
aW5kZXggNWJiMzcyNS4uZDM5MGU5YyAxMDA2NDQKLS0tIGEvdGVzdHMvZGF0YS9NYWtlZmls
ZS5hbQorKysgYi90ZXN0cy9kYXRhL01ha2VmaWxlLmFtCkBAIC04Miw2ICs4Miw3IEBAIHRl
c3QxMjIwIFwKIHRlc3QxMzAwIHRlc3QxMzAxIHRlc3QxMzAyIHRlc3QxMzAzIHRlc3QxMzA0
IHRlc3QxMzA1CVwKIHRlc3QxMzA2IHRlc3QxMzA3IHRlc3QxMzA4IHRlc3QxMzA5IHRlc3Qx
MzEwIHRlc3QxMzExIHRlc3QxMzEyIHRlc3QxMzEzIFwKIHRlc3QxMzE0IHRlc3QxMzE1IFwK
K3Rlc3QxNDAwIHRlc3QxNDAxIHRlc3QxNDAyIHRlc3QxNDAzIHRlc3QxNDA0IHRlc3QxNDA1
IHRlc3QxNDA2IHRlc3QxNDA3IFwKIHRlc3QyMDAwIHRlc3QyMDAxIHRlc3QyMDAyIHRlc3Qy
MDAzIHRlc3QyMDA0CiAKIEVYVFJBX0RJU1QgPSAkKFRFU1RDQVNFUykgRElTQUJMRUQKZGlm
ZiAtLWdpdCBhL3Rlc3RzL2RhdGEvdGVzdDE0MDAgYi90ZXN0cy9kYXRhL3Rlc3QxNDAwCm5l
dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3YjI3NDUKLS0tIC9kZXYvbnVs
bAorKysgYi90ZXN0cy9kYXRhL3Rlc3QxNDAwCkBAIC0wLDAgKzEsOTIgQEAKKzx0ZXN0Y2Fz
ZT4KKzxpbmZvPgorPGtleXdvcmRzPgorSFRUUAorbGliY3VybAorPC9rZXl3b3Jkcz4KKzwv
aW5mbz4KKworIyBTZXJ2ZXItc2lkZQorPHJlcGx5PgorPGRhdGE+CitIVFRQLzEuMSAyMDAg
T0sNCitEYXRlOiBUaHUsIDI5IEp1bCAyMDA4IDE0OjQ5OjAwIEdNVA0KK1NlcnZlcjogdGVz
dC1zZXJ2ZXIvZmFrZQ0KK0NvbnRlbnQtTGVuZ3RoOiAwDQorQ29ubmVjdGlvbjogY2xvc2UN
CisNCis8L2RhdGE+Cis8L3JlcGx5PgorCisjIENsaWVudC1zaWRlCis8Y2xpZW50PgorPHNl
cnZlcj4KK2h0dHAKKzwvc2VydmVyPgorIDxuYW1lPgorLS1saWJjdXJsIGZvciBzaW1wbGUg
SFRUUCBHRVQKKyA8L25hbWU+CisgPGNvbW1hbmQ+CitodHRwOi8vJUhPU1RJUDolSFRUUFBP
UlQvd2Uvd2FudC8xNDAwIC0tbGliY3VybCBsb2cvdGVzdDE0MDAuYworPC9jb21tYW5kPgor
PC9jbGllbnQ+CisKKyMgVmVyaWZ5IGRhdGEgYWZ0ZXIgdGhlIHRlc3QgaGFzIGJlZW4gInNo
b3QiCis8dmVyaWZ5PgorPHN0cmlwPgorXlVzZXItQWdlbnQ6LioKKzwvc3RyaXA+Cis8cHJv
dG9jb2w+CitHRVQgL3dlL3dhbnQvMTQwMCBIVFRQLzEuMQ0KK1VzZXItQWdlbnQ6IGN1cmwv
Ny4xOC4yIChpNjg2LXBjLWxpbnV4LWdudSkgbGliY3VybC83LjE4LjIgT3BlblNTTC8wLjku
N2EgaXB2NiB6bGliLzEuMS40DQorSG9zdDogJUhPU1RJUDolSFRUUFBPUlQNCitBY2NlcHQ6
ICovKg0KKw0KKzwvcHJvdG9jb2w+Cis8c3RyaXBmaWxlPgorcy8oVVNFUkFHRU5ULCBcIilb
XlwiXSsvJHsxfXN0cmlwcGVkLworPC9zdHJpcGZpbGU+Cis8ZmlsZSBuYW1lPSJsb2cvdGVz
dDE0MDAuYyI+CisvKioqKioqKioqIFNhbXBsZSBjb2RlIGdlbmVyYXRlZCBieSB0aGUgY3Vy
bCBjb21tYW5kIGxpbmUgdG9vbCAqKioqKioqKioqCisgKiBBbGwgY3VybF9lYXN5X3NldG9w
dCgpIG9wdGlvbnMgYXJlIGRvY3VtZW50ZWQgYXQ6CisgKiBodHRwOi8vY3VybC5oYXh4LnNl
L2xpYmN1cmwvYy9jdXJsX2Vhc3lfc2V0b3B0Lmh0bWwKKyAqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiov
CisjaW5jbHVkZSA8Y3VybC9jdXJsLmg+CisKK2ludCBtYWluKGludCBhcmdjLCBjaGFyICph
cmd2W10pCit7CisgIENVUkxjb2RlIHJldDsKKyAgQ1VSTCAqaG5kID0gY3VybF9lYXN5X2lu
aXQoKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVVJMLCAiaHR0cDovLyVI
T1NUSVA6JUhUVFBQT1JUL3dlL3dhbnQvMTQwMCIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhu
ZCwgQ1VSTE9QVF9IRUFERVIsIDFMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxP
UFRfVVNFUkFHRU5ULCAic3RyaXBwZWQiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENV
UkxPUFRfTUFYUkVESVJTLCA1MEwpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9Q
VF9TU0xfVkVSSUZZUEVFUiwgMUwpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9Q
VF9WRVJCT1NFLCAxTCk7CisgIHJldCA9IGN1cmxfZWFzeV9wZXJmb3JtKGhuZCk7CisgIGN1
cmxfZWFzeV9jbGVhbnVwKGhuZCk7CisKKyAgLyogSGVyZSBpcyBhIGxpc3Qgb2Ygb3B0aW9u
cyB0aGUgY3VybCBjb2RlIHVzZWQgdGhhdCBjYW5ub3QgZ2V0IGdlbmVyYXRlZAorICAgICBh
cyBzb3VyY2UgZWFzaWx5LiBZb3UgbWF5IHNlbGVjdCB0byBlaXRoZXIgbm90IHVzZSB0aGVt
IG9yIGltcGxlbWVudAorICAgICB0aGVtIHlvdXJzZWxmLgorCisgIENVUkxPUFRfV1JJVEVE
QVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9XUklURUZVTkNUSU9OIHNl
dCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX1JFQUREQVRBIHNldCB0byBhIG9i
amVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9SRUFERlVOQ1RJT04gc2V0IHRvIGEgZnVuY3Rpb25w
b2ludGVyCisgIENVUkxPUFRfU0VFS0RBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBD
VVJMT1BUX1NFRUtGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9Q
VF9FUlJPUkJVRkZFUiBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRfU1RERVJS
IHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9ERUJVR0ZVTkNUSU9OIHNldCB0
byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX0RFQlVHREFUQSBzZXQgdG8gYSBvYmpl
Y3Rwb2ludGVyCisgIENVUkxPUFRfU09DS09QVEZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9u
cG9pbnRlcgorICBDVVJMT1BUX1NPQ0tPUFREQVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIK
KworICAqLworICByZXR1cm4gKGludClyZXQ7Cit9CisvKioqKiBFbmQgb2Ygc2FtcGxlIGNv
ZGUgKioqKi8KKzwvZmlsZT4KKzwvdmVyaWZ5PgorPC90ZXN0Y2FzZT4KZGlmZiAtLWdpdCBh
L3Rlc3RzL2RhdGEvdGVzdDE0MDEgYi90ZXN0cy9kYXRhL3Rlc3QxNDAxCm5ldyBmaWxlIG1v
ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY2ZWNjMzIKLS0tIC9kZXYvbnVsbAorKysgYi90
ZXN0cy9kYXRhL3Rlc3QxNDAxCkBAIC0wLDAgKzEsMTA4IEBACis8dGVzdGNhc2U+Cis8aW5m
bz4KKzxrZXl3b3Jkcz4KK0hUVFAKK0hUVFAgQmFzaWMgYXV0aAorLS1saWJjdXJsCis8L2tl
eXdvcmRzPgorPC9pbmZvPgorCisjIFNlcnZlci1zaWRlCis8cmVwbHk+Cis8ZGF0YT4KK0hU
VFAvMS4xIDIwMCBPSw0KK0RhdGU6IFRodSwgMjkgSnVsIDIwMDggMTQ6NDk6MDAgR01UDQor
U2VydmVyOiB0ZXN0LXNlcnZlci9mYWtlDQorQ29udGVudC1MZW5ndGg6IDANCitDb250ZW50
LVR5cGU6IHRleHQvcGxhaW4NCitDb25uZWN0aW9uOiBjbG9zZQ0KKw0KKzwvZGF0YT4KKzwv
cmVwbHk+CisKKyMgQ2xpZW50LXNpZGUKKzxjbGllbnQ+Cis8c2VydmVyPgoraHR0cAorPC9z
ZXJ2ZXI+CisgPG5hbWU+CistLWxpYmN1cmwgZm9yIEdFVCB3aXRoIHZhcmlvdXMgb3B0aW9u
cworIDwvbmFtZT4KKyA8Y29tbWFuZD4KK2h0dHA6Ly8lSE9TVElQOiVIVFRQUE9SVC93ZS93
YW50LzE0MDEgLS1saWJjdXJsIGxvZy90ZXN0MTQwMS5jIC0tYmFzaWMgLXUgZmFrZTp1c2Vy
IC1IICJYLUZpbGVzOiBNdWxkZXIiIC1IICJYLU1lbjogY3ljbG9wcywgaWNlbWFuIiAtQSBN
eVVBIC1iIGNob2NvbGF0ZT1jaGlwIC0tcHJvdG8gIj1odHRwLGZ0cCxmaWxlIgorPC9jb21t
YW5kPgorPC9jbGllbnQ+CisKKyMgVmVyaWZ5IGRhdGEgYWZ0ZXIgdGhlIHRlc3QgaGFzIGJl
ZW4gInNob3QiCis8dmVyaWZ5PgorPHN0cmlwPgorXlVzZXItQWdlbnQ6LioKKzwvc3RyaXA+
Cis8cHJvdG9jb2w+CitHRVQgL3dlL3dhbnQvMTQwMSBIVFRQLzEuMQ0KK1VzZXItQWdlbnQ6
IHN0cmlwcGVkDQorQXV0aG9yaXphdGlvbjogQmFzaWMgWm1GclpUcDFjMlZ5DQorSG9zdDog
JUhPU1RJUDolSFRUUFBPUlQNCitBY2NlcHQ6ICovKg0KK0Nvb2tpZTogY2hvY29sYXRlPWNo
aXANCitYLUZpbGVzOiBNdWxkZXINCitYLU1lbjogY3ljbG9wcywgaWNlbWFuDQorDQorPC9w
cm90b2NvbD4KKzxmaWxlIG5hbWU9ImxvZy90ZXN0MTQwMS5jIj4KKy8qKioqKioqKiogU2Ft
cGxlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBjdXJsIGNvbW1hbmQgbGluZSB0b29sICoqKioq
KioqKioKKyAqIEFsbCBjdXJsX2Vhc3lfc2V0b3B0KCkgb3B0aW9ucyBhcmUgZG9jdW1lbnRl
ZCBhdDoKKyAqIGh0dHA6Ly9jdXJsLmhheHguc2UvbGliY3VybC9jL2N1cmxfZWFzeV9zZXRv
cHQuaHRtbAorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKyNpbmNsdWRlIDxjdXJsL2N1cmwuaD4K
KworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgQ1VSTGNvZGUgcmV0
OworICBzdHJ1Y3QgY3VybF9zbGlzdCAqc2xpc3QwID0gTlVMTDsKKyAgQ1VSTCAqaG5kID0g
Y3VybF9lYXN5X2luaXQoKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVVJM
LCAiaHR0cDovLyVIT1NUSVA6JUhUVFBQT1JUL3dlL3dhbnQvMTQwMSIpOworICBjdXJsX2Vh
c3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9IRUFERVIsIDFMKTsKKyAgY3VybF9lYXN5X3NldG9w
dChobmQsIENVUkxPUFRfVVNFUlBXRCwgImZha2U6dXNlciIpOworICBjdXJsX2Vhc3lfc2V0
b3B0KGhuZCwgQ1VSTE9QVF9VU0VSQUdFTlQsICJNeVVBIik7CisgIHNsaXN0MCA9IGN1cmxf
c2xpc3RfYXBwZW5kKHNsaXN0MCwgIlgtRmlsZXM6IE11bGRlciIpOworICBzbGlzdDAgPSBj
dXJsX3NsaXN0X2FwcGVuZChzbGlzdDAsICJYLU1lbjogY3ljbG9wcywgaWNlbWFuIik7Cisg
IGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX0hUVFBIRUFERVIsIHNsaXN0MCk7Cisg
IGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX01BWFJFRElSUywgNTBMKTsKKyAgY3Vy
bF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfSFRUUEFVVEgsIChsb25nKUNVUkxBVVRIX0JB
U0lDKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIs
IDFMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfQ09PS0lFLCAiY2hvY29s
YXRlPWNoaXAiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVkVSQk9TRSwg
MUwpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9QUk9UT0NPTFMsIChsb25n
KUNVUkxQUk9UT19GSUxFIHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAobG9uZylDVVJMUFJPVE9fRlRQIHwKKyAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAobG9uZylDVVJMUFJPVE9fSFRUUCk7CisgIHJldCA9IGN1
cmxfZWFzeV9wZXJmb3JtKGhuZCk7CisgIGN1cmxfZWFzeV9jbGVhbnVwKGhuZCk7CisgIGN1
cmxfc2xpc3RfZnJlZV9hbGwoc2xpc3QwKTsKKworICAvKiBIZXJlIGlzIGEgbGlzdCBvZiBv
cHRpb25zIHRoZSBjdXJsIGNvZGUgdXNlZCB0aGF0IGNhbm5vdCBnZXQgZ2VuZXJhdGVkCisg
ICAgIGFzIHNvdXJjZSBlYXNpbHkuIFlvdSBtYXkgc2VsZWN0IHRvIGVpdGhlciBub3QgdXNl
IHRoZW0gb3IgaW1wbGVtZW50CisgICAgIHRoZW0geW91cnNlbGYuCisKKyAgQ1VSTE9QVF9X
UklURURBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1dSSVRFRlVOQ1RJ
T04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfUkVBRERBVEEgc2V0IHRv
IGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1JFQURGVU5DVElPTiBzZXQgdG8gYSBmdW5j
dGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVy
CisgIENVUkxPUFRfU0VFS0ZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBD
VVJMT1BUX0VSUk9SQlVGRkVSIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9T
VERFUlIgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX0RFQlVHRlVOQ1RJT04g
c2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfREVCVUdEQVRBIHNldCB0byBh
IG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NLT1BURlVOQ1RJT04gc2V0IHRvIGEgZnVu
Y3Rpb25wb2ludGVyCisgIENVUkxPUFRfU09DS09QVERBVEEgc2V0IHRvIGEgb2JqZWN0cG9p
bnRlcgorCisgICovCisgIHJldHVybiAoaW50KXJldDsKK30KKy8qKioqIEVuZCBvZiBzYW1w
bGUgY29kZSAqKioqLworPC9maWxlPgorPHN0ZG91dD4KKzwvc3Rkb3V0PgorPC92ZXJpZnk+
Cis8L3Rlc3RjYXNlPgpkaWZmIC0tZ2l0IGEvdGVzdHMvZGF0YS90ZXN0MTQwMiBiL3Rlc3Rz
L2RhdGEvdGVzdDE0MDIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDMw
OGM0YQotLS0gL2Rldi9udWxsCisrKyBiL3Rlc3RzL2RhdGEvdGVzdDE0MDIKQEAgLTAsMCAr
MSwxMDIgQEAKKzx0ZXN0Y2FzZT4KKzxpbmZvPgorPGtleXdvcmRzPgorSFRUUAorSFRUUCBQ
T1NUCistLWxpYmN1cmwKKzwva2V5d29yZHM+Cis8L2luZm8+CisKKyMgU2VydmVyLXNpZGUK
KzxyZXBseT4KKzxkYXRhPgorSFRUUC8xLjEgMjAwIE9LDQorRGF0ZTogVGh1LCAyOSBKdWwg
MjAwOCAxNDo0OTowMCBHTVQNCitTZXJ2ZXI6IHRlc3Qtc2VydmVyL2Zha2UNCitDb250ZW50
LUxlbmd0aDogMA0KK0NvbnRlbnQtVHlwZTogdGV4dC9wbGFpbg0KK0Nvbm5lY3Rpb246IGNs
b3NlDQorDQorPC9kYXRhPgorPC9yZXBseT4KKworIyBDbGllbnQtc2lkZQorPGNsaWVudD4K
KzxzZXJ2ZXI+CitodHRwCis8L3NlcnZlcj4KKyA8bmFtZT4KKy0tbGliY3VybCBmb3Igc2lt
cGxlIFBPU1QKKyA8L25hbWU+CisgPGNvbW1hbmQ+CitodHRwOi8vJUhPU1RJUDolSFRUUFBP
UlQvd2Uvd2FudC8xNDAyIC0tbGliY3VybCBsb2cvdGVzdDE0MDIuYyAtZCAiZm9vPWJhciIg
LWQgImJhej1xdXV4IgorPC9jb21tYW5kPgorPC9jbGllbnQ+CisKKyMgVmVyaWZ5IGRhdGEg
YWZ0ZXIgdGhlIHRlc3QgaGFzIGJlZW4gInNob3QiCis8dmVyaWZ5PgorPHN0cmlwPgorXlVz
ZXItQWdlbnQ6LioKKzwvc3RyaXA+Cis8cHJvdG9jb2wgbm9uZXdsaW5lPSJ5ZXMiPgorUE9T
VCAvd2Uvd2FudC8xNDAyIEhUVFAvMS4xDQorVXNlci1BZ2VudDogY3VybC83LjE4LjIgKGk2
ODYtcGMtbGludXgtZ251KSBsaWJjdXJsLzcuMTguMiBPcGVuU1NMLzAuOS43YSBpcHY2IHps
aWIvMS4xLjQNCitIb3N0OiAlSE9TVElQOiVIVFRQUE9SVA0KK0FjY2VwdDogKi8qDQorQ29u
dGVudC1MZW5ndGg6IDE2DQorQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXd3dy1mb3Jt
LXVybGVuY29kZWQNCisNCitmb289YmFyJmJhej1xdXV4Cis8L3Byb3RvY29sPgorPHN0cmlw
ZmlsZT4KKyMgY3VybCdzIGRlZmF1bHQgdXNlci1hZ2VudCB2YXJpZXMgd2l0aCB2ZXJzaW9u
LCBsaWJyYXJpZXMgZXRjLgorcy8oVVNFUkFHRU5ULCBcIilbXlwiXSsvJHsxfXN0cmlwcGVk
LworPC9zdHJpcGZpbGU+Cis8ZmlsZSBuYW1lPSJsb2cvdGVzdDE0MDIuYyI+CisvKioqKioq
KioqIFNhbXBsZSBjb2RlIGdlbmVyYXRlZCBieSB0aGUgY3VybCBjb21tYW5kIGxpbmUgdG9v
bCAqKioqKioqKioqCisgKiBBbGwgY3VybF9lYXN5X3NldG9wdCgpIG9wdGlvbnMgYXJlIGRv
Y3VtZW50ZWQgYXQ6CisgKiBodHRwOi8vY3VybC5oYXh4LnNlL2xpYmN1cmwvYy9jdXJsX2Vh
c3lfc2V0b3B0Lmh0bWwKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisjaW5jbHVkZSA8Y3VybC9j
dXJsLmg+CisKK2ludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pCit7CisgIENVUkxj
b2RlIHJldDsKKyAgQ1VSTCAqaG5kID0gY3VybF9lYXN5X2luaXQoKTsKKyAgY3VybF9lYXN5
X3NldG9wdChobmQsIENVUkxPUFRfVVJMLCAiaHR0cDovLyVIT1NUSVA6JUhUVFBQT1JUL3dl
L3dhbnQvMTQwMiIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9IRUFERVIs
IDFMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfUE9TVEZJRUxEUywgImZv
bz1iYXImYmF6PXF1dXgiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfUE9T
VEZJRUxEU0laRV9MQVJHRSwgKGN1cmxfb2ZmX3QpMTYpOworICBjdXJsX2Vhc3lfc2V0b3B0
KGhuZCwgQ1VSTE9QVF9VU0VSQUdFTlQsICJzdHJpcHBlZCIpOworICBjdXJsX2Vhc3lfc2V0
b3B0KGhuZCwgQ1VSTE9QVF9NQVhSRURJUlMsIDUwTCk7CisgIGN1cmxfZWFzeV9zZXRvcHQo
aG5kLCBDVVJMT1BUX1NTTF9WRVJJRllQRUVSLCAxTCk7CisgIGN1cmxfZWFzeV9zZXRvcHQo
aG5kLCBDVVJMT1BUX1ZFUkJPU0UsIDFMKTsKKyAgcmV0ID0gY3VybF9lYXN5X3BlcmZvcm0o
aG5kKTsKKyAgY3VybF9lYXN5X2NsZWFudXAoaG5kKTsKKworICAvKiBIZXJlIGlzIGEgbGlz
dCBvZiBvcHRpb25zIHRoZSBjdXJsIGNvZGUgdXNlZCB0aGF0IGNhbm5vdCBnZXQgZ2VuZXJh
dGVkCisgICAgIGFzIHNvdXJjZSBlYXNpbHkuIFlvdSBtYXkgc2VsZWN0IHRvIGVpdGhlciBu
b3QgdXNlIHRoZW0gb3IgaW1wbGVtZW50CisgICAgIHRoZW0geW91cnNlbGYuCisKKyAgQ1VS
TE9QVF9XUklURURBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1dSSVRF
RlVOQ1RJT04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfUkVBRERBVEEg
c2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1JFQURGVU5DVElPTiBzZXQgdG8g
YSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLREFUQSBzZXQgdG8gYSBvYmplY3Rw
b2ludGVyCisgIENVUkxPUFRfU0VFS0ZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRl
cgorICBDVVJMT1BUX0VSUk9SQlVGRkVSIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VS
TE9QVF9TVERFUlIgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX0RFQlVHRlVO
Q1RJT04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfREVCVUdEQVRBIHNl
dCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NLT1BURlVOQ1RJT04gc2V0IHRv
IGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfU09DS09QVERBVEEgc2V0IHRvIGEgb2Jq
ZWN0cG9pbnRlcgorCisgICovCisgIHJldHVybiAoaW50KXJldDsKK30KKy8qKioqIEVuZCBv
ZiBzYW1wbGUgY29kZSAqKioqLworPC9maWxlPgorPHN0ZG91dD4KKzwvc3Rkb3V0PgorPC92
ZXJpZnk+Cis8L3Rlc3RjYXNlPgpkaWZmIC0tZ2l0IGEvdGVzdHMvZGF0YS90ZXN0MTQwMyBi
L3Rlc3RzL2RhdGEvdGVzdDE0MDMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw
MC4uMTA4YzU4MgotLS0gL2Rldi9udWxsCisrKyBiL3Rlc3RzL2RhdGEvdGVzdDE0MDMKQEAg
LTAsMCArMSw5NyBAQAorPHRlc3RjYXNlPgorPGluZm8+Cis8a2V5d29yZHM+CitIVFRQCitI
VFRQIEdFVAorLS1saWJjdXJsCis8L2tleXdvcmRzPgorPC9pbmZvPgorCisjIFNlcnZlci1z
aWRlCis8cmVwbHk+Cis8ZGF0YT4KK0hUVFAvMS4xIDIwMCBPSw0KK0RhdGU6IFRodSwgMjkg
SnVsIDIwMDggMTQ6NDk6MDAgR01UDQorU2VydmVyOiB0ZXN0LXNlcnZlci9mYWtlDQorQ29u
dGVudC1MZW5ndGg6IDANCitDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCitDb25uZWN0aW9u
OiBjbG9zZQ0KKw0KKzwvZGF0YT4KKzwvcmVwbHk+CisKKyMgQ2xpZW50LXNpZGUKKzxjbGll
bnQ+Cis8c2VydmVyPgoraHR0cAorPC9zZXJ2ZXI+CisgPG5hbWU+CistLWxpYmN1cmwgZm9y
IEdFVCB3aXRoIHF1ZXJ5CisgPC9uYW1lPgorIDxjb21tYW5kPgoraHR0cDovLyVIT1NUSVA6
JUhUVFBQT1JUL3dlL3dhbnQvMTQwMyAtLWxpYmN1cmwgbG9nL3Rlc3QxNDAzLmMgLUcgLWQg
ImZvbz1iYXIiIC1kICJiYXo9cXV1eCIKKzwvY29tbWFuZD4KKzwvY2xpZW50PgorCisjIFZl
cmlmeSBkYXRhIGFmdGVyIHRoZSB0ZXN0IGhhcyBiZWVuICJzaG90IgorPHZlcmlmeT4KKzxz
dHJpcD4KK15Vc2VyLUFnZW50Oi4qCis8L3N0cmlwPgorPHByb3RvY29sPgorR0VUIC93ZS93
YW50LzE0MDM/Zm9vPWJhciZiYXo9cXV1eCBIVFRQLzEuMQ0KK1VzZXItQWdlbnQ6IGN1cmwv
Ny4xOC4yIChpNjg2LXBjLWxpbnV4LWdudSkgbGliY3VybC83LjE4LjIgT3BlblNTTC8wLjku
N2EgaXB2NiB6bGliLzEuMS40DQorSG9zdDogJUhPU1RJUDolSFRUUFBPUlQNCitBY2NlcHQ6
ICovKg0KKw0KKzwvcHJvdG9jb2w+Cis8c3RyaXBmaWxlPgorIyBjdXJsJ3MgZGVmYXVsdCB1
c2VyLWFnZW50IHZhcmllcyB3aXRoIHZlcnNpb24sIGxpYnJhcmllcyBldGMuCitzLyhVU0VS
QUdFTlQsIFwiKVteXCJdKy8kezF9c3RyaXBwZWQvCis8L3N0cmlwZmlsZT4KKzxmaWxlIG5h
bWU9ImxvZy90ZXN0MTQwMy5jIj4KKy8qKioqKioqKiogU2FtcGxlIGNvZGUgZ2VuZXJhdGVk
IGJ5IHRoZSBjdXJsIGNvbW1hbmQgbGluZSB0b29sICoqKioqKioqKioKKyAqIEFsbCBjdXJs
X2Vhc3lfc2V0b3B0KCkgb3B0aW9ucyBhcmUgZG9jdW1lbnRlZCBhdDoKKyAqIGh0dHA6Ly9j
dXJsLmhheHguc2UvbGliY3VybC9jL2N1cmxfZWFzeV9zZXRvcHQuaHRtbAorICoqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKi8KKyNpbmNsdWRlIDxjdXJsL2N1cmwuaD4KKworaW50IG1haW4oaW50IGFy
Z2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgQ1VSTGNvZGUgcmV0OworICBDVVJMICpobmQgPSBj
dXJsX2Vhc3lfaW5pdCgpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9VUkws
ICJodHRwOi8vJUhPU1RJUDolSFRUUFBPUlQvd2Uvd2FudC8xNDAzP2Zvbz1iYXImYmF6PXF1
dXgiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfSEVBREVSLCAxTCk7Cisg
IGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX1VTRVJBR0VOVCwgInN0cmlwcGVkIik7
CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX01BWFJFRElSUywgNTBMKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIsIDFMKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVkVSQk9TRSwgMUwpOworICByZXQgPSBj
dXJsX2Vhc3lfcGVyZm9ybShobmQpOworICBjdXJsX2Vhc3lfY2xlYW51cChobmQpOworCisg
IC8qIEhlcmUgaXMgYSBsaXN0IG9mIG9wdGlvbnMgdGhlIGN1cmwgY29kZSB1c2VkIHRoYXQg
Y2Fubm90IGdldCBnZW5lcmF0ZWQKKyAgICAgYXMgc291cmNlIGVhc2lseS4gWW91IG1heSBz
ZWxlY3QgdG8gZWl0aGVyIG5vdCB1c2UgdGhlbSBvciBpbXBsZW1lbnQKKyAgICAgdGhlbSB5
b3Vyc2VsZi4KKworICBDVVJMT1BUX1dSSVRFREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVy
CisgIENVUkxPUFRfV1JJVEVGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAg
Q1VSTE9QVF9SRUFEREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRfUkVB
REZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX1NFRUtEQVRB
IHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLRlVOQ1RJT04gc2V0IHRv
IGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfRVJST1JCVUZGRVIgc2V0IHRvIGEgb2Jq
ZWN0cG9pbnRlcgorICBDVVJMT1BUX1NUREVSUiBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisg
IENVUkxPUFRfREVCVUdGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VS
TE9QVF9ERUJVR0RBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1NPQ0tP
UFRGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NLT1BU
REFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisKKyAgKi8KKyAgcmV0dXJuIChpbnQpcmV0
OworfQorLyoqKiogRW5kIG9mIHNhbXBsZSBjb2RlICoqKiovCis8L2ZpbGU+Cis8c3Rkb3V0
PgorPC9zdGRvdXQ+Cis8L3ZlcmlmeT4KKzwvdGVzdGNhc2U+CmRpZmYgLS1naXQgYS90ZXN0
cy9kYXRhL3Rlc3QxNDA0IGIvdGVzdHMvZGF0YS90ZXN0MTQwNApuZXcgZmlsZSBtb2RlIDEw
MDY0NAppbmRleCAwMDAwMDAwLi43ODgwNjIxCi0tLSAvZGV2L251bGwKKysrIGIvdGVzdHMv
ZGF0YS90ZXN0MTQwNApAQCAtMCwwICsxLDE0NiBAQAorPHRlc3RjYXNlPgorIyBCYXNlZCBv
biB0ZXN0IDEzMTUKKzxpbmZvPgorPGtleXdvcmRzPgorSFRUUAorSFRUUCBGT1JNUE9TVAor
SFRUUCBmaWxlIHVwbG9hZAorLS1saWJjdXJsCis8L2tleXdvcmRzPgorPC9pbmZvPgorCisj
IFNlcnZlci1zaWRlCis8cmVwbHk+Cis8ZGF0YT4KK0hUVFAvMS4xIDIwMCBPSworRGF0ZTog
VGh1LCAyOSBKdWwgMjAwOCAxNDo0OTowMCBHTVQKK1NlcnZlcjogdGVzdC1zZXJ2ZXIvZmFr
ZQorQ29udGVudC1MZW5ndGg6IDAKK0Nvbm5lY3Rpb246IGNsb3NlCisKKzwvZGF0YT4KKzwv
cmVwbHk+CisKKyMgQ2xpZW50LXNpZGUKKzxjbGllbnQ+Cis8c2VydmVyPgoraHR0cAorPC9z
ZXJ2ZXI+CisgPG5hbWU+CitIVFRQIFJGQzE4NjctdHlwZSBmb3JtcG9zdGluZyAtIC1GIHdp
dGggdGhyZWUgZmlsZXMsIG9uZSB3aXRoIGV4cGxpY2l0IHR5cGUKKyA8L25hbWU+CisgPGNv
bW1hbmQ+CitodHRwOi8vJUhPU1RJUDolSFRUUFBPUlQvd2Uvd2FudC8xNDA0IC1GIG5hbWU9
dmFsdWUgLUYgJ2ZpbGU9QGxvZy90ZXN0MTQwNC50eHQsbG9nL3Rlc3QxNDA0LnR4dDt0eXBl
PW1hZ2ljL2NvbnRlbnQsbG9nL3Rlc3QxNDA0LnR4dCcgLS1saWJjdXJsIGxvZy90ZXN0MTQw
NC5jCis8L2NvbW1hbmQ+CisjIFdlIGNyZWF0ZSB0aGlzIGZpbGUgYmVmb3JlIHRoZSBjb21t
YW5kIGlzIGludm9rZWQhCis8ZmlsZSBuYW1lPSJsb2cvdGVzdDE0MDQudHh0Ij4KK2R1bW15
IGRhdGEKKzwvZmlsZT4KKzwvY2xpZW50PgorCisjIFZlcmlmeSBkYXRhIGFmdGVyIHRoZSB0
ZXN0IGhhcyBiZWVuICJzaG90IgorPHZlcmlmeT4KKzxzdHJpcD4KKyheVXNlci1BZ2VudDou
KnwtLS0tLStcdyspCis8L3N0cmlwPgorPHByb3RvY29sPgorUE9TVCAvd2Uvd2FudC8xNDA0
IEhUVFAvMS4xDQorVXNlci1BZ2VudDogY3VybC83LjE4LjIgKGk2ODYtcGMtbGludXgtZ251
KSBsaWJjdXJsLzcuMTguMiBPcGVuU1NMLzAuOS43YSBpcHY2IHpsaWIvMS4xLjQNCitIb3N0
OiAlSE9TVElQOiVIVFRQUE9SVA0KK0FjY2VwdDogKi8qDQorQ29udGVudC1MZW5ndGg6IDc5
NQ0KK0V4cGVjdDogMTAwLWNvbnRpbnVlDQorQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvZm9y
bS1kYXRhOyBib3VuZGFyeT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tOWVmOGQ2MjA1
NzYzDQorDQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tOWVmOGQ2MjA1NzYzDQor
Q29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJuYW1lIg0KKw0KK3ZhbHVl
DQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tOWVmOGQ2MjA1NzYzDQorQ29udGVu
dC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmaWxlIg0KK0NvbnRlbnQtVHlwZTog
bXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
YWFhYWFhYWFhYWFhDQorDQorQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmls
ZW5hbWU9InRlc3QxNDA0LnR4dCINCitDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCisNCitk
dW1teSBkYXRhCisNCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS05ZWY4ZDYyMDU3
NjMNCitDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0idGVzdDE0
MDQudHh0Ig0KK0NvbnRlbnQtVHlwZTogbWFnaWMvY29udGVudA0KKw0KK2R1bW15IGRhdGEK
Kw0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTllZjhkNjIwNTc2Mw0KK0NvbnRl
bnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPSJ0ZXN0MTQwNC50eHQiDQor
Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluDQorDQorZHVtbXkgZGF0YQorDQorLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tYWFhYWFhYWFhYWFhLS0NCistLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS05ZWY4ZDYyMDU3NjMtLQ0KKzwvcHJvdG9jb2w+Cis8c3RyaXBmaWxl
PgorIyBjdXJsJ3MgZGVmYXVsdCB1c2VyLWFnZW50IHZhcmllcyB3aXRoIHZlcnNpb24sIGxp
YnJhcmllcyBldGMuCitzLyhVU0VSQUdFTlQsIFwiKVteXCJdKy8kezF9c3RyaXBwZWQvCis8
L3N0cmlwZmlsZT4KKzxmaWxlIG5hbWU9ImxvZy90ZXN0MTQwNC5jIj4KKy8qKioqKioqKiog
U2FtcGxlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBjdXJsIGNvbW1hbmQgbGluZSB0b29sICoq
KioqKioqKioKKyAqIEFsbCBjdXJsX2Vhc3lfc2V0b3B0KCkgb3B0aW9ucyBhcmUgZG9jdW1l
bnRlZCBhdDoKKyAqIGh0dHA6Ly9jdXJsLmhheHguc2UvbGliY3VybC9jL2N1cmxfZWFzeV9z
ZXRvcHQuaHRtbAorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKyNpbmNsdWRlIDxjdXJsL2N1cmwu
aD4KKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgQ1VSTGNvZGUg
cmV0OworICBzdHJ1Y3QgY3VybF9odHRwcG9zdCAqcG9zdCA9IE5VTEwsICplbmQgPSBOVUxM
OworICBDVVJMICpobmQgPSBjdXJsX2Vhc3lfaW5pdCgpOworICBjdXJsX2Vhc3lfc2V0b3B0
KGhuZCwgQ1VSTE9QVF9VUkwsICJodHRwOi8vJUhPU1RJUDolSFRUUFBPUlQvd2Uvd2FudC8x
NDA0Iik7CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX0hFQURFUiwgMUwpOwor
ICBjdXJsX2Zvcm1hZGQoJnBvc3QsICZlbmQsCisgICAgICAgICAgICAgICBDVVJMRk9STV9D
T1BZTkFNRSwgIm5hbWUiLAorICAgICAgICAgICAgICAgQ1VSTEZPUk1fQ09QWUNPTlRFTlRT
LCAidmFsdWUiLAorICAgICAgICAgICAgICAgQ1VSTEZPUk1fRU5EKTsKKyAgY3VybF9mb3Jt
YWRkKCZwb3N0LCAmZW5kLAorICAgICAgICAgICAgICAgQ1VSTEZPUk1fQ09QWU5BTUUsICJm
aWxlIiwKKyAgICAgICAgICAgICAgIENVUkxGT1JNX0ZJTEUsICJsb2cvdGVzdDE0MDQudHh0
IiwKKyAgICAgICAgICAgICAgIENVUkxGT1JNX0NPTlRFTlRUWVBFLCAidGV4dC9wbGFpbiIs
CisgICAgICAgICAgICAgICBDVVJMRk9STV9GSUxFLCAibG9nL3Rlc3QxNDA0LnR4dCIsCisg
ICAgICAgICAgICAgICBDVVJMRk9STV9DT05URU5UVFlQRSwgIm1hZ2ljL2NvbnRlbnQiLAor
ICAgICAgICAgICAgICAgQ1VSTEZPUk1fRklMRSwgImxvZy90ZXN0MTQwNC50eHQiLAorICAg
ICAgICAgICAgICAgQ1VSTEZPUk1fQ09OVEVOVFRZUEUsICJ0ZXh0L3BsYWluIiwKKyAgICAg
ICAgICAgICAgIENVUkxGT1JNX0VORCk7CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJM
T1BUX0hUVFBQT1NULCBwb3N0KTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRf
VVNFUkFHRU5ULCAic3RyaXBwZWQiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxP
UFRfTUFYUkVESVJTLCA1MEwpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9T
U0xfVkVSSUZZUEVFUiwgMUwpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9W
RVJCT1NFLCAxTCk7CisgIHJldCA9IGN1cmxfZWFzeV9wZXJmb3JtKGhuZCk7CisgIGN1cmxf
ZWFzeV9jbGVhbnVwKGhuZCk7CisgIGN1cmxfZm9ybWZyZWUocG9zdCk7CisKKyAgLyogSGVy
ZSBpcyBhIGxpc3Qgb2Ygb3B0aW9ucyB0aGUgY3VybCBjb2RlIHVzZWQgdGhhdCBjYW5ub3Qg
Z2V0IGdlbmVyYXRlZAorICAgICBhcyBzb3VyY2UgZWFzaWx5LiBZb3UgbWF5IHNlbGVjdCB0
byBlaXRoZXIgbm90IHVzZSB0aGVtIG9yIGltcGxlbWVudAorICAgICB0aGVtIHlvdXJzZWxm
LgorCisgIENVUkxPUFRfV1JJVEVEQVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VS
TE9QVF9XUklURUZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BU
X1JFQUREQVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9SRUFERlVOQ1RJ
T04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfU0VFS0RBVEEgc2V0IHRv
IGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1NFRUtGVU5DVElPTiBzZXQgdG8gYSBmdW5j
dGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9FUlJPUkJVRkZFUiBzZXQgdG8gYSBvYmplY3Rwb2lu
dGVyCisgIENVUkxPUFRfU1RERVJSIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9Q
VF9ERUJVR0ZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX0RF
QlVHREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRfU09DS09QVEZVTkNU
SU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX1NPQ0tPUFREQVRBIHNl
dCB0byBhIG9iamVjdHBvaW50ZXIKKworICAqLworICByZXR1cm4gKGludClyZXQ7Cit9Cisv
KioqKiBFbmQgb2Ygc2FtcGxlIGNvZGUgKioqKi8KKzwvZmlsZT4KKzwvdmVyaWZ5PgorPC90
ZXN0Y2FzZT4KZGlmZiAtLWdpdCBhL3Rlc3RzL2RhdGEvdGVzdDE0MDUgYi90ZXN0cy9kYXRh
L3Rlc3QxNDA1Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmOWM4NjEK
LS0tIC9kZXYvbnVsbAorKysgYi90ZXN0cy9kYXRhL3Rlc3QxNDA1CkBAIC0wLDAgKzEsMTIw
IEBACis8dGVzdGNhc2U+CisjIERlcml2ZWQgZnJvbSB0ZXN0MjI3Cis8aW5mbz4KKzxrZXl3
b3Jkcz4KK0ZUUAorcG9zdC1xdW90ZQorcHJlLXF1b3RlCitxdW90ZQorLS1saWJjdXJsCis8
L2tleXdvcmRzPgorPC9pbmZvPgorIyBTZXJ2ZXItc2lkZQorPHJlcGx5PgorPGRhdGE+Citk
YXRhCisgICAgdG8KKyAgICAgIHNlZQordGhhdCBGVFAKK3dvcmtzCisgIHNvIGRvZXMgaXQ/
Cis8L2RhdGE+Cis8c2VydmVyY21kPgorUkVQTFkgRVBTViA1MDAgbm8gc3VjaCBjb21tYW5k
CitSRVBMWSBGQUlMIDUwMCB0aGlzIG1pZ2h0IG5vdCBiZSBhIGZhaWx1cmUhCis8L3NlcnZl
cmNtZD4KKzwvcmVwbHk+CisKKyMgQ2xpZW50LXNpZGUKKzxjbGllbnQ+Cis8c2VydmVyPgor
ZnRwCis8L3NlcnZlcj4KKyA8bmFtZT4KK0ZUUCB3aXRoIHF1b3RlIG9wcworIDwvbmFtZT4K
KyA8Y29tbWFuZD4KK2Z0cDovLyVIT1NUSVA6JUZUUFBPUlQvMTQwNSAtUSAiTk9PUCAxIiAt
USAiK05PT1AgMiIgLVEgIi1OT09QIDMiIC1RICIqRkFJTCIgLVEgIisqRkFJTCBIQVJEIiAt
LWxpYmN1cmwgbG9nL3Rlc3QxNDA1LmMKKzwvY29tbWFuZD4KKzwvY2xpZW50PgorCisjIFZl
cmlmeSBkYXRhIGFmdGVyIHRoZSB0ZXN0IGhhcyBiZWVuICJzaG90IgorPHZlcmlmeT4KKzxw
cm90b2NvbD4KK1VTRVIgYW5vbnltb3VzDQorUEFTUyBmdHBAZXhhbXBsZS5jb20NCitQV0QN
CitOT09QIDENCitGQUlMDQorRVBTVg0KK1BBU1YNCitUWVBFIEkNCitOT09QIDINCitGQUlM
IEhBUkQNCitTSVpFIDE0MDUNCitSRVRSIDE0MDUNCitOT09QIDMNCitRVUlUDQorPC9wcm90
b2NvbD4KKzxmaWxlIG5hbWU9ImxvZy90ZXN0MTQwNS5jIj4KKy8qKioqKioqKiogU2FtcGxl
IGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBjdXJsIGNvbW1hbmQgbGluZSB0b29sICoqKioqKioq
KioKKyAqIEFsbCBjdXJsX2Vhc3lfc2V0b3B0KCkgb3B0aW9ucyBhcmUgZG9jdW1lbnRlZCBh
dDoKKyAqIGh0dHA6Ly9jdXJsLmhheHguc2UvbGliY3VybC9jL2N1cmxfZWFzeV9zZXRvcHQu
aHRtbAorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKi8KKyNpbmNsdWRlIDxjdXJsL2N1cmwuaD4KKwor
aW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgQ1VSTGNvZGUgcmV0Owor
ICBzdHJ1Y3QgY3VybF9zbGlzdCAqc2xpc3QwID0gTlVMTDsKKyAgc3RydWN0IGN1cmxfc2xp
c3QgKnNsaXN0MSA9IE5VTEw7CisgIHN0cnVjdCBjdXJsX3NsaXN0ICpzbGlzdDIgPSBOVUxM
OworICBDVVJMICpobmQgPSBjdXJsX2Vhc3lfaW5pdCgpOworICBjdXJsX2Vhc3lfc2V0b3B0
KGhuZCwgQ1VSTE9QVF9VUkwsICJmdHA6Ly8lSE9TVElQOiVGVFBQT1JULzE0MDUiKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfSEVBREVSLCAxTCk7CisgIGN1cmxfZWFz
eV9zZXRvcHQoaG5kLCBDVVJMT1BUX1VTRVJBR0VOVCwgInN0cmlwcGVkIik7CisgIGN1cmxf
ZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX01BWFJFRElSUywgNTBMKTsKKyAgY3VybF9lYXN5
X3NldG9wdChobmQsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIsIDFMKTsKKyAgc2xpc3QwID0g
Y3VybF9zbGlzdF9hcHBlbmQoc2xpc3QwLCAiTk9PUCAxIik7CisgIHNsaXN0MCA9IGN1cmxf
c2xpc3RfYXBwZW5kKHNsaXN0MCwgIipGQUlMIik7CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5k
LCBDVVJMT1BUX1FVT1RFLCBzbGlzdDApOworICBzbGlzdDEgPSBjdXJsX3NsaXN0X2FwcGVu
ZChzbGlzdDEsICJOT09QIDMiKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRf
UE9TVFFVT1RFLCBzbGlzdDEpOworICBzbGlzdDIgPSBjdXJsX3NsaXN0X2FwcGVuZChzbGlz
dDIsICJOT09QIDIiKTsKKyAgc2xpc3QyID0gY3VybF9zbGlzdF9hcHBlbmQoc2xpc3QyLCAi
KkZBSUwgSEFSRCIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9QUkVRVU9U
RSwgc2xpc3QyKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVkVSQk9TRSwg
MUwpOworICByZXQgPSBjdXJsX2Vhc3lfcGVyZm9ybShobmQpOworICBjdXJsX2Vhc3lfY2xl
YW51cChobmQpOworICBjdXJsX3NsaXN0X2ZyZWVfYWxsKHNsaXN0MCk7CisgIGN1cmxfc2xp
c3RfZnJlZV9hbGwoc2xpc3QxKTsKKyAgY3VybF9zbGlzdF9mcmVlX2FsbChzbGlzdDIpOwor
CisgIC8qIEhlcmUgaXMgYSBsaXN0IG9mIG9wdGlvbnMgdGhlIGN1cmwgY29kZSB1c2VkIHRo
YXQgY2Fubm90IGdldCBnZW5lcmF0ZWQKKyAgICAgYXMgc291cmNlIGVhc2lseS4gWW91IG1h
eSBzZWxlY3QgdG8gZWl0aGVyIG5vdCB1c2UgdGhlbSBvciBpbXBsZW1lbnQKKyAgICAgdGhl
bSB5b3Vyc2VsZi4KKworICBDVVJMT1BUX1dSSVRFREFUQSBzZXQgdG8gYSBvYmplY3Rwb2lu
dGVyCisgIENVUkxPUFRfV1JJVEVGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIK
KyAgQ1VSTE9QVF9SRUFEREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRf
UkVBREZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX1NFRUtE
QVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLRlVOQ1RJT04gc2V0
IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfRVJST1JCVUZGRVIgc2V0IHRvIGEg
b2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1NUREVSUiBzZXQgdG8gYSBvYmplY3Rwb2ludGVy
CisgIENVUkxPUFRfREVCVUdGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAg
Q1VSTE9QVF9ERUJVR0RBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1NP
Q0tPUFRGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NL
T1BUREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisKKyAgKi8KKyAgcmV0dXJuIChpbnQp
cmV0OworfQorLyoqKiogRW5kIG9mIHNhbXBsZSBjb2RlICoqKiovCis8L2ZpbGU+Cis8c3Ry
aXBmaWxlPgorIyBjdXJsJ3MgZGVmYXVsdCB1c2VyLWFnZW50IHZhcmllcyB3aXRoIHZlcnNp
b24sIGxpYnJhcmllcyBldGMuCitzLyhVU0VSQUdFTlQsIFwiKVteXCJdKy8kezF9c3RyaXBw
ZWQvCis8L3N0cmlwZmlsZT4KKzwvdmVyaWZ5PgorPC90ZXN0Y2FzZT4KZGlmZiAtLWdpdCBh
L3Rlc3RzL2RhdGEvdGVzdDE0MDYgYi90ZXN0cy9kYXRhL3Rlc3QxNDA2Cm5ldyBmaWxlIG1v
ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI4YzkwOTcKLS0tIC9kZXYvbnVsbAorKysgYi90
ZXN0cy9kYXRhL3Rlc3QxNDA2CkBAIC0wLDAgKzEsMTEwIEBACis8dGVzdGNhc2U+CisjIEJh
c2VkIG9uIHRlc3Q4MDIKKyMgTi5CLiAtLWxpYmN1cmwgb3V0cHV0IG5vdCBzdWZmaWNpZW50
IHRvIGRlYWwgd2l0aCB1cGxvYWRlZCBmaWxlcy4KKzxpbmZvPgorPGtleXdvcmRzPgorU01U
UAorLS1saWJjdXJsCis8L2tleXdvcmRzPgorPC9pbmZvPgorCisjCisjIFNlcnZlci1zaWRl
Cis8cmVwbHk+Cis8L3JlcGx5PgorCisjCisjIENsaWVudC1zaWRlCis8Y2xpZW50PgorPHNl
cnZlcj4KK3NtdHAKKzwvc2VydmVyPgorIDxuYW1lPgorU01UUAorIDwvbmFtZT4KKzxmaWxl
IG5hbWU9ImxvZy90ZXN0MTQwNi5lbWwiPgorRnJvbTogZGlmZmVyZW50CitUbzogYW5vdGhl
cgorCitib2R5Cis8L2ZpbGU+CisgPGNvbW1hbmQ+CitzbXRwOi8vJUhPU1RJUDolU01UUFBP
UlQvdXNlciAtLW1haWwtcmNwdCAxNDA2QGZvbyAtLW1haWwtcmNwdCAxNDA2QGZvb2Jhci5l
eGFtcGxlIC0tbWFpbC1mcm9tIDE0MDZAZnJvbSAtVCBsb2cvdGVzdDE0MDYuZW1sIC0tbGli
Y3VybCBsb2cvdGVzdDE0MDYuYworPC9jb21tYW5kPgorPC9jbGllbnQ+CisKKyMKKyMgVmVy
aWZ5IGRhdGEgYWZ0ZXIgdGhlIHRlc3QgaGFzIGJlZW4gInNob3QiCis8dmVyaWZ5PgorPHBy
b3RvY29sPgorRUhMTyB1c2VyDQorTUFJTCBGUk9NOjwxNDA2QGZyb20+IFNJWkU9MzQNCitS
Q1BUIFRPOjwxNDA2QGZvbz4NCitSQ1BUIFRPOjwxNDA2QGZvb2Jhci5leGFtcGxlPg0KK0RB
VEENCitRVUlUDQorPC9wcm90b2NvbD4KKzx1cGxvYWQ+CitGcm9tOiBkaWZmZXJlbnQKK1Rv
OiBhbm90aGVyCisKK2JvZHkKKw0KKy4NCis8L3VwbG9hZD4KKzxmaWxlIG5hbWU9ImxvZy90
ZXN0MTQwNi5jIj4KKy8qKioqKioqKiogU2FtcGxlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBj
dXJsIGNvbW1hbmQgbGluZSB0b29sICoqKioqKioqKioKKyAqIEFsbCBjdXJsX2Vhc3lfc2V0
b3B0KCkgb3B0aW9ucyBhcmUgZG9jdW1lbnRlZCBhdDoKKyAqIGh0dHA6Ly9jdXJsLmhheHgu
c2UvbGliY3VybC9jL2N1cmxfZWFzeV9zZXRvcHQuaHRtbAorICoqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
Ki8KKyNpbmNsdWRlIDxjdXJsL2N1cmwuaD4KKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIg
KmFyZ3ZbXSkKK3sKKyAgQ1VSTGNvZGUgcmV0OworICBzdHJ1Y3QgY3VybF9zbGlzdCAqc2xp
c3QwID0gTlVMTDsKKyAgQ1VSTCAqaG5kID0gY3VybF9lYXN5X2luaXQoKTsKKyAgY3VybF9l
YXN5X3NldG9wdChobmQsIENVUkxPUFRfSU5GSUxFU0laRV9MQVJHRSwgKGN1cmxfb2ZmX3Qp
MzQpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9VUkwsICJzbXRwOi8vJUhP
U1RJUDolU01UUFBPUlQvdXNlciIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9Q
VF9IRUFERVIsIDFMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVVBMT0FE
LCAxTCk7CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX1VTRVJBR0VOVCwgInN0
cmlwcGVkIik7CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX01BWFJFRElSUywg
NTBMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIs
IDFMKTsKKyAgY3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVkVSQk9TRSwgMUwpOwor
ICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9NQUlMX0ZST00sICIxNDA2QGZyb20i
KTsKKyAgc2xpc3QwID0gY3VybF9zbGlzdF9hcHBlbmQoc2xpc3QwLCAiMTQwNkBmb28iKTsK
KyAgc2xpc3QwID0gY3VybF9zbGlzdF9hcHBlbmQoc2xpc3QwLCAiMTQwNkBmb29iYXIuZXhh
bXBsZSIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9NQUlMX1JDUFQsIHNs
aXN0MCk7CisgIHJldCA9IGN1cmxfZWFzeV9wZXJmb3JtKGhuZCk7CisgIGN1cmxfZWFzeV9j
bGVhbnVwKGhuZCk7CisgIGN1cmxfc2xpc3RfZnJlZV9hbGwoc2xpc3QwKTsKKworICAvKiBI
ZXJlIGlzIGEgbGlzdCBvZiBvcHRpb25zIHRoZSBjdXJsIGNvZGUgdXNlZCB0aGF0IGNhbm5v
dCBnZXQgZ2VuZXJhdGVkCisgICAgIGFzIHNvdXJjZSBlYXNpbHkuIFlvdSBtYXkgc2VsZWN0
IHRvIGVpdGhlciBub3QgdXNlIHRoZW0gb3IgaW1wbGVtZW50CisgICAgIHRoZW0geW91cnNl
bGYuCisKKyAgQ1VSTE9QVF9XUklURURBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBD
VVJMT1BUX1dSSVRFRlVOQ1RJT04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxP
UFRfUkVBRERBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1JFQURGVU5D
VElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLREFUQSBzZXQg
dG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRfU0VFS0ZVTkNUSU9OIHNldCB0byBhIGZ1
bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX0VSUk9SQlVGRkVSIHNldCB0byBhIG9iamVjdHBv
aW50ZXIKKyAgQ1VSTE9QVF9TVERFUlIgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJM
T1BUX0RFQlVHRlVOQ1RJT04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRf
REVCVUdEQVRBIHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NLT1BURlVO
Q1RJT04gc2V0IHRvIGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfU09DS09QVERBVEEg
c2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorCisgICovCisgIHJldHVybiAoaW50KXJldDsKK30K
Ky8qKioqIEVuZCBvZiBzYW1wbGUgY29kZSAqKioqLworPC9maWxlPgorPHN0cmlwZmlsZT4K
KyMgY3VybCdzIGRlZmF1bHQgdXNlci1hZ2VudCB2YXJpZXMgd2l0aCB2ZXJzaW9uLCBsaWJy
YXJpZXMgZXRjLgorcy8oVVNFUkFHRU5ULCBcIilbXlwiXSsvJHsxfXN0cmlwcGVkLworPC9z
dHJpcGZpbGU+Cis8L3ZlcmlmeT4KKzwvdGVzdGNhc2U+CmRpZmYgLS1naXQgYS90ZXN0cy9k
YXRhL3Rlc3QxNDA3IGIvdGVzdHMvZGF0YS90ZXN0MTQwNwpuZXcgZmlsZSBtb2RlIDEwMDY0
NAppbmRleCAwMDAwMDAwLi44MjEyOTI2Ci0tLSAvZGV2L251bGwKKysrIGIvdGVzdHMvZGF0
YS90ZXN0MTQwNwpAQCAtMCwwICsxLDkxIEBACis8dGVzdGNhc2U+CisjIEJhc2VkIG9uIHRl
c3Q4MDgKKzxpbmZvPgorPGtleXdvcmRzPgorUE9QMworTElTVAorLS1saWJjdXJsCis8L2tl
eXdvcmRzPgorPC9pbmZvPgorCisjCisjIFNlcnZlci1zaWRlCis8cmVwbHk+Cis8c2VydmVy
Y21kPgorUkVQTFkgTElTVCArT0sgMTQwNyAxMDAKKzwvc2VydmVyY21kPgorPC9yZXBseT4K
KworIworIyBDbGllbnQtc2lkZQorPGNsaWVudD4KKzxzZXJ2ZXI+Citwb3AzCis8L3NlcnZl
cj4KKyA8bmFtZT4KK1BPUDMgTElTVCBvbmUgbWVzc2FnZQorIDwvbmFtZT4KKyA8Y29tbWFu
ZD4KK3BvcDM6Ly8lSE9TVElQOiVQT1AzUE9SVC8xNDA3IC1sIC11IHVzZXI6c2VjcmV0IC0t
bGliY3VybCBsb2cvdGVzdDE0MDcuYworPC9jb21tYW5kPgorPC9jbGllbnQ+CisKKyMKKyMg
VmVyaWZ5IGRhdGEgYWZ0ZXIgdGhlIHRlc3QgaGFzIGJlZW4gInNob3QiCis8dmVyaWZ5Pgor
PHByb3RvY29sPgorVVNFUiB1c2VyDQorUEFTUyBzZWNyZXQNCitMSVNUIDE0MDcNCitRVUlU
DQorPC9wcm90b2NvbD4KKzxmaWxlIG5hbWU9ImxvZy90ZXN0MTQwNy5jIj4KKy8qKioqKioq
KiogU2FtcGxlIGNvZGUgZ2VuZXJhdGVkIGJ5IHRoZSBjdXJsIGNvbW1hbmQgbGluZSB0b29s
ICoqKioqKioqKioKKyAqIEFsbCBjdXJsX2Vhc3lfc2V0b3B0KCkgb3B0aW9ucyBhcmUgZG9j
dW1lbnRlZCBhdDoKKyAqIGh0dHA6Ly9jdXJsLmhheHguc2UvbGliY3VybC9jL2N1cmxfZWFz
eV9zZXRvcHQuaHRtbAorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKyNpbmNsdWRlIDxjdXJsL2N1
cmwuaD4KKworaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKK3sKKyAgQ1VSTGNv
ZGUgcmV0OworICBDVVJMICpobmQgPSBjdXJsX2Vhc3lfaW5pdCgpOworICBjdXJsX2Vhc3lf
c2V0b3B0KGhuZCwgQ1VSTE9QVF9VUkwsICJwb3AzOi8vJUhPU1RJUDolUE9QM1BPUlQvMTQw
NyIpOworICBjdXJsX2Vhc3lfc2V0b3B0KGhuZCwgQ1VSTE9QVF9IRUFERVIsIDFMKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfRElSTElTVE9OTFksIDFMKTsKKyAgY3Vy
bF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVVNFUlBXRCwgInVzZXI6c2VjcmV0Iik7Cisg
IGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX1VTRVJBR0VOVCwgInN0cmlwcGVkIik7
CisgIGN1cmxfZWFzeV9zZXRvcHQoaG5kLCBDVVJMT1BUX01BWFJFRElSUywgNTBMKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIsIDFMKTsKKyAg
Y3VybF9lYXN5X3NldG9wdChobmQsIENVUkxPUFRfVkVSQk9TRSwgMUwpOworICByZXQgPSBj
dXJsX2Vhc3lfcGVyZm9ybShobmQpOworICBjdXJsX2Vhc3lfY2xlYW51cChobmQpOworCisg
IC8qIEhlcmUgaXMgYSBsaXN0IG9mIG9wdGlvbnMgdGhlIGN1cmwgY29kZSB1c2VkIHRoYXQg
Y2Fubm90IGdldCBnZW5lcmF0ZWQKKyAgICAgYXMgc291cmNlIGVhc2lseS4gWW91IG1heSBz
ZWxlY3QgdG8gZWl0aGVyIG5vdCB1c2UgdGhlbSBvciBpbXBsZW1lbnQKKyAgICAgdGhlbSB5
b3Vyc2VsZi4KKworICBDVVJMT1BUX1dSSVRFREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVy
CisgIENVUkxPUFRfV1JJVEVGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAg
Q1VSTE9QVF9SRUFEREFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisgIENVUkxPUFRfUkVB
REZVTkNUSU9OIHNldCB0byBhIGZ1bmN0aW9ucG9pbnRlcgorICBDVVJMT1BUX1NFRUtEQVRB
IHNldCB0byBhIG9iamVjdHBvaW50ZXIKKyAgQ1VSTE9QVF9TRUVLRlVOQ1RJT04gc2V0IHRv
IGEgZnVuY3Rpb25wb2ludGVyCisgIENVUkxPUFRfRVJST1JCVUZGRVIgc2V0IHRvIGEgb2Jq
ZWN0cG9pbnRlcgorICBDVVJMT1BUX1NUREVSUiBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisg
IENVUkxPUFRfREVCVUdGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VS
TE9QVF9ERUJVR0RBVEEgc2V0IHRvIGEgb2JqZWN0cG9pbnRlcgorICBDVVJMT1BUX1NPQ0tP
UFRGVU5DVElPTiBzZXQgdG8gYSBmdW5jdGlvbnBvaW50ZXIKKyAgQ1VSTE9QVF9TT0NLT1BU
REFUQSBzZXQgdG8gYSBvYmplY3Rwb2ludGVyCisKKyAgKi8KKyAgcmV0dXJuIChpbnQpcmV0
OworfQorLyoqKiogRW5kIG9mIHNhbXBsZSBjb2RlICoqKiovCis8L2ZpbGU+Cis8c3RyaXBm
aWxlPgorIyBjdXJsJ3MgZGVmYXVsdCB1c2VyLWFnZW50IHZhcmllcyB3aXRoIHZlcnNpb24s
IGxpYnJhcmllcyBldGMuCitzLyhVU0VSQUdFTlQsIFwiKVteXCJdKy8kezF9c3RyaXBwZWQv
Cis8L3N0cmlwZmlsZT4KKzwvdmVyaWZ5PgorPC90ZXN0Y2FzZT4KLS0gCjEuNi41LjYKCg==
--------------080201030400000102030306
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
--------------080201030400000102030306--
Received on 2001-09-17