{"id":7568,"date":"2026-04-03T07:49:32","date_gmt":"2026-04-03T06:49:32","guid":{"rendered":"https:\/\/workboot.fr\/ciela\/?page_id=7568"},"modified":"2026-04-14T15:54:27","modified_gmt":"2026-04-14T14:54:27","slug":"sockets-en-c-ansi","status":"publish","type":"page","link":"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/","title":{"rendered":"Socket TCP en C ansi"},"content":{"rendered":"\n<nav aria-label=\"Table des mati\u00e8res\" class=\"wp-block-table-of-contents\"><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#serveur-tcp\">Serveur TCP<\/a><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#makefile\">Makefile<\/a><\/li><\/ol><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#client-tcp\">Client TCP<\/a><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#makefile-1\">Makefile<\/a><\/li><\/ol><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#muti-serveur-fork\">Muti_serveur (fork)<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#serveur-http\">Serveur http <\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/#serveur-http-multi-client\">Serveur http multi-client<\/a><\/li><\/ol><\/nav>\n\n\n\n<pre class=\"wp-block-code\"><code>serveur_fd = socket(AF_INET, SOCK_STREAM, 0)\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AF_INET : Famille d&rsquo;adresses IPv4<\/li>\n\n\n\n<li>SOCK_STREAM : Type de socket (TCP, fiable, connexion orient\u00e9e flux)<\/li>\n\n\n\n<li>0 : Protocole par d\u00e9faut (TCP pour SOCK_STREAM)<\/li>\n\n\n\n<li>Retour : Descripteur de fichier (entier) ou -1 si erreur<\/li>\n<\/ul>\n\n\n\n<h2 id=\"serveur-tcp\" class=\"wp-block-heading\">Serveur TCP<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n#include &lt;netdb.h>\n\n#define PORT 8888\n#define BUFFER_SIZE 1024\n\nint main(int argc, char *argv[]) {\n    int sock_fd;\n    struct sockaddr_in adresse_serveur;\n    struct hostent *serveur;\n    char buffer[BUFFER_SIZE];\n    char message[BUFFER_SIZE];\n    int bytes_recus;\n    struct in_addr **addr_list;  \/* Pour une version plus explicite *\/\n\n    \/* V\u00e9rification des arguments *\/\n    if (argc &lt; 2) {\n        fprintf(stderr, \"Usage: %s &lt;adresse_serveur>\\n\", argv[0]);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 1. Cr\u00e9ation du socket *\/\n    sock_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (sock_fd &lt; 0) {\n        perror(\"Erreur cr\u00e9ation socket\");\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 2. R\u00e9solution du nom d'h\u00f4te *\/\n    serveur = gethostbyname(argv[1]);\n    if (serveur == NULL) {\n        fprintf(stderr, \"H\u00f4te inconnu : %s\\n\", argv[1]);\n        close(sock_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 3. Configuration de l'adresse *\/\n    memset(&amp;adresse_serveur, 0, sizeof(adresse_serveur));\n    adresse_serveur.sin_family = AF_INET;\n    \n    \/* M\u00e9thode alternative plus explicite *\/\n    addr_list = (struct in_addr **)serveur->h_addr_list;\n    adresse_serveur.sin_addr = *addr_list[0];\n    adresse_serveur.sin_port = htons(PORT);\n\n    \/* 4. Connexion au serveur *\/\n    if (connect(sock_fd, (struct sockaddr *)&amp;adresse_serveur, sizeof(adresse_serveur)) &lt; 0) {\n        perror(\"Erreur connect\");\n        close(sock_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"Connect\u00e9 au serveur %s:%d\\n\", argv[1], PORT);\n    printf(\"Adresse IP : %s\\n\", inet_ntoa(adresse_serveur.sin_addr));\n\n    \/* 5. \u00c9change de donn\u00e9es *\/\n    while (1) {\n        printf(\"Message \u00e0 envoyer (ou 'quit' pour quitter) : \");\n        fgets(message, BUFFER_SIZE, stdin);\n        \n        \/* Suppression du saut de ligne *\/\n        message[strcspn(message, \"\\n\")] = '\\0';\n        \n        if (strcmp(message, \"quit\") == 0) {\n            break;\n        }\n        \n        \/* Envoi *\/\n        send(sock_fd, message, strlen(message), 0);\n        \n        \/* R\u00e9ception de la r\u00e9ponse *\/\n        bytes_recus = recv(sock_fd, buffer, BUFFER_SIZE - 1, 0);\n        if (bytes_recus &lt;= 0) {\n            printf(\"Serveur d\u00e9connect\u00e9\\n\");\n            break;\n        }\n        \n        buffer[bytes_recus] = '\\0';\n        printf(\"R\u00e9ponse du serveur : %s\\n\", buffer);\n    }\n\n    \/* 6. Fermeture *\/\n    close(sock_fd);\n    return 0;\n}<\/pre>\n\n\n\n<h3 id=\"makefile\" class=\"wp-block-heading\">Makefile<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"md\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CC = gcc\nCFLAGS = -Wall -Wextra -ansi -pedantic\n\nall: serveur\n\nserveur: serveur_tcp.c\n\t$(CC) $(CFLAGS) -o serveur serveur_tcp.c\n\nclean:\n\trm -f serveur\n\n.PHONY: all clean\n<\/pre>\n\n\n\n<h2 id=\"client-tcp\" class=\"wp-block-heading\">Client TCP<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n#include &lt;netdb.h>\n\n#define PORT 8888\n#define BUFFER_SIZE 1024\n\nint main(int argc, char *argv[]) {\n    int sock_fd;\n    struct sockaddr_in adresse_serveur;\n    struct hostent *serveur;\n    char buffer[BUFFER_SIZE];\n    char message[BUFFER_SIZE];\n    int bytes_recus;\n    struct in_addr **addr_list;  \/* Pour une version plus explicite *\/\n\n    \/* V\u00e9rification des arguments *\/\n    if (argc &lt; 2) {\n        fprintf(stderr, \"Usage: %s &lt;adresse_serveur>\\n\", argv[0]);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 1. Cr\u00e9ation du socket *\/\n    sock_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (sock_fd &lt; 0) {\n        perror(\"Erreur cr\u00e9ation socket\");\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 2. R\u00e9solution du nom d'h\u00f4te *\/\n    serveur = gethostbyname(argv[1]);\n    if (serveur == NULL) {\n        fprintf(stderr, \"H\u00f4te inconnu : %s\\n\", argv[1]);\n        close(sock_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* 3. Configuration de l'adresse *\/\n    memset(&amp;adresse_serveur, 0, sizeof(adresse_serveur));\n    adresse_serveur.sin_family = AF_INET;\n    \n    \/* M\u00e9thode alternative plus explicite *\/\n    addr_list = (struct in_addr **)serveur->h_addr_list;\n    adresse_serveur.sin_addr = *addr_list[0];\n    adresse_serveur.sin_port = htons(PORT);\n\n    \/* 4. Connexion au serveur *\/\n    if (connect(sock_fd, (struct sockaddr *)&amp;adresse_serveur, sizeof(adresse_serveur)) &lt; 0) {\n        perror(\"Erreur connect\");\n        close(sock_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"Connect\u00e9 au serveur %s:%d\\n\", argv[1], PORT);\n    printf(\"Adresse IP : %s\\n\", inet_ntoa(adresse_serveur.sin_addr));\n\n    \/* 5. \u00c9change de donn\u00e9es *\/\n    while (1) {\n        printf(\"Message \u00e0 envoyer (ou 'quit' pour quitter) : \");\n        fgets(message, BUFFER_SIZE, stdin);\n        \n        \/* Suppression du saut de ligne *\/\n        message[strcspn(message, \"\\n\")] = '\\0';\n        \n        if (strcmp(message, \"quit\") == 0) {\n            break;\n        }\n        \n        \/* Envoi *\/\n        send(sock_fd, message, strlen(message), 0);\n        \n        \/* R\u00e9ception de la r\u00e9ponse *\/\n        bytes_recus = recv(sock_fd, buffer, BUFFER_SIZE - 1, 0);\n        if (bytes_recus &lt;= 0) {\n            printf(\"Serveur d\u00e9connect\u00e9\\n\");\n            break;\n        }\n        \n        buffer[bytes_recus] = '\\0';\n        printf(\"R\u00e9ponse du serveur : %s\\n\", buffer);\n    }\n\n    \/* 6. Fermeture *\/\n    close(sock_fd);\n    return 0;\n}<\/pre>\n\n\n\n<h3 id=\"makefile-1\" class=\"wp-block-heading\">Makefile<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"md\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CC = gcc\nCFLAGS = -Wall -Wextra -ansi -pedantic\n\nall: client\n\nclient: client_tcp.c\n\t$(CC) $(CFLAGS) -o client client_tcp.c\n\nclean:\n\trm -f client\n\n.PHONY: all clean\n<\/pre>\n\n\n\n<h2 id=\"muti-serveur-fork\" class=\"wp-block-heading\">Muti_serveur (fork)<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;sys\/wait.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n#include &lt;signal.h>\n\n#define PORT 8888\n#define BUFFER_SIZE 1024\n#define MAX_CLIENTS 10\n\n\/* Gestionnaire de signaux pour \u00e9viter les processus zombies *\/\nvoid gestionnaire_sigchld(int signo) {\n    \/* waitpid avec WNOHANG pour ne pas bloquer *\/\n    while (waitpid(-1, NULL, WNOHANG) > 0);\n}\n\n\/* Fonction pour traiter chaque client *\/\nvoid traiter_client(int client_fd, struct sockaddr_in adresse_client) {\n    char buffer[BUFFER_SIZE];\n    int bytes_lus;\n    int i;\n    char client_ip[INET_ADDRSTRLEN];\n    \n    \/* Convertir l'adresse IP en cha\u00eene *\/\n    inet_ntop(AF_INET, &amp;adresse_client.sin_addr, client_ip, INET_ADDRSTRLEN);\n    printf(\"[Processus %d] Client connect\u00e9 : %s:%d\\n\", \n           getpid(), \n           client_ip, \n           ntohs(adresse_client.sin_port));\n    \n    \/* Communication avec le client *\/\n    while ((bytes_lus = recv(client_fd, buffer, BUFFER_SIZE - 1, 0)) > 0) {\n        buffer[bytes_lus] = '\\0';\n        printf(\"[Processus %d] Re\u00e7u : %s\", getpid(), buffer);\n        \n        \/* Conversion en majuscules *\/\n        for (i = 0; i &lt; bytes_lus; i++) {\n            if (buffer[i] >= 'a' &amp;&amp; buffer[i] &lt;= 'z') {\n                buffer[i] = buffer[i] - 'a' + 'A';\n            }\n        }\n        \n        \/* Envoi de la r\u00e9ponse *\/\n        send(client_fd, buffer, bytes_lus, 0);\n    }\n    \n    if (bytes_lus == 0) {\n        printf(\"[Processus %d] Client d\u00e9connect\u00e9\\n\", getpid());\n    } else {\n        perror(\"[Processus %d] Erreur recv\");\n    }\n    \n    close(client_fd);\n    printf(\"[Processus %d] Connexion ferm\u00e9e, processus termine\\n\", getpid());\n    exit(0);  \/* Le processus fils se termine *\/\n}\n\nint main(void) {\n    int serveur_fd, client_fd;\n    struct sockaddr_in adresse_serveur, adresse_client;\n    socklen_t taille_client = sizeof(adresse_client);\n    struct sigaction sa;\n    int opt = 1;\n    \n    \/* 1. Configuration du gestionnaire de signaux pour \u00e9viter les zombies *\/\n    sa.sa_handler = gestionnaire_sigchld;\n    sigemptyset(&amp;sa.sa_mask);\n    sa.sa_flags = SA_RESTART;  \/* R\u00e9initialiser les appels syst\u00e8me interrompus *\/\n    if (sigaction(SIGCHLD, &amp;sa, NULL) == -1) {\n        perror(\"Erreur sigaction\");\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* 2. Cr\u00e9ation du socket *\/\n    serveur_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (serveur_fd &lt; 0) {\n        perror(\"Erreur cr\u00e9ation socket\");\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* 3. Option pour r\u00e9utiliser l'adresse (\u00e9vite \"Address already in use\") *\/\n    if (setsockopt(serveur_fd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt)) &lt; 0) {\n        perror(\"Erreur setsockopt\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* 4. Configuration de l'adresse du serveur *\/\n    memset(&amp;adresse_serveur, 0, sizeof(adresse_serveur));\n    adresse_serveur.sin_family = AF_INET;\n    adresse_serveur.sin_addr.s_addr = INADDR_ANY;\n    adresse_serveur.sin_port = htons(PORT);\n    \n    \/* 5. Attachement du socket *\/\n    if (bind(serveur_fd, (struct sockaddr *)&amp;adresse_serveur, sizeof(adresse_serveur)) &lt; 0) {\n        perror(\"Erreur bind\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* 6. Mise en \u00e9coute *\/\n    if (listen(serveur_fd, MAX_CLIENTS) &lt; 0) {\n        perror(\"Erreur listen\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n    \n    printf(\"Serveur multi-clients d\u00e9marr\u00e9 sur le port %d\\n\", PORT);\n    printf(\"PID du serveur principal : %d\\n\", getpid());\n    printf(\"En attente de connexions...\\n\\n\");\n    \n    \/* 7. Boucle principale d'acceptation *\/\n    while (1) {\n        \/* Accepter une nouvelle connexion *\/\n        client_fd = accept(serveur_fd, (struct sockaddr *)&amp;adresse_client, &amp;taille_client);\n        if (client_fd &lt; 0) {\n            perror(\"Erreur accept\");\n            continue;\n        }\n        \n        \/* Cr\u00e9ation d'un processus fils pour g\u00e9rer le client *\/\n        pid_t pid = fork();\n        \n        if (pid &lt; 0) {\n            perror(\"Erreur fork\");\n            close(client_fd);\n            continue;\n        }\n        \n        if (pid == 0) {\n            \/* Processus fils *\/\n            close(serveur_fd);  \/* Le fils n'a pas besoin du socket d'\u00e9coute *\/\n            traiter_client(client_fd, adresse_client);\n            \/* Ne jamais arriver ici *\/\n        } else {\n            \/* Processus p\u00e8re *\/\n            close(client_fd);   \/* Le p\u00e8re n'a pas besoin du socket client *\/\n            printf(\"[P\u00e8re %d] Nouveau client connect\u00e9, processus fils cr\u00e9\u00e9 : %d\\n\", \n                   getpid(), pid);\n        }\n    }\n    \n    \/* 8. Fermeture (jamais atteint dans cet exemple) *\/\n    close(serveur_fd);\n    return 0;\n}<\/pre>\n\n\n\n<h2 id=\"serveur-http\" class=\"wp-block-heading\">Serveur http <\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* serveur_http_minimal.c - Version simplifi\u00e9e pour tester *\/\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n\n#define PORT 8080\n#define BUFFER_SIZE 4096\n\nint main(void) {\n    int serveur_fd, client_fd;\n    struct sockaddr_in adresse_serveur, adresse_client;\n    socklen_t taille_client = sizeof(adresse_client);\n    char buffer[BUFFER_SIZE];\n    int bytes_lus;\n    char *reponse_ok = \"HTTP\/1.1 200 OK\\r\\n\"\n                       \"Content-Type: text\/html\\r\\n\"\n                       \"Content-Length: 135\\r\\n\"\n                       \"Connection: close\\r\\n\"\n                       \"\\r\\n\"\n                       \"&lt;!DOCTYPE html>\\n\"\n                       \"&lt;html>\\n\"\n                       \"&lt;head>&lt;title>Test Serveur&lt;\/title>&lt;\/head>\\n\"\n                       \"&lt;body>\\n\"\n                       \"&lt;h1>Bienvenue sur mon serveur HTTP!&lt;\/h1>\\n\"\n                       \"&lt;p>Ceci est une reponse HTML.&lt;\/p>\\n\"\n                       \"&lt;\/body>\\n\"\n                       \"&lt;\/html>\\n\";\n    \n    char *reponse_404 = \"HTTP\/1.1 404 Not Found\\r\\n\"\n                        \"Content-Type: text\/html\\r\\n\"\n                        \"Content-Length: 105\\r\\n\"\n                        \"Connection: close\\r\\n\"\n                        \"\\r\\n\"\n                        \"&lt;!DOCTYPE html>\\n\"\n                        \"&lt;html>\\n\"\n                        \"&lt;body>\\n\"\n                        \"&lt;h1>404 - Page non trouvee&lt;\/h1>\\n\"\n                        \"&lt;\/body>\\n\"\n                        \"&lt;\/html>\\n\";\n\n    \/* Cr\u00e9ation socket *\/\n    serveur_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (serveur_fd &lt; 0) {\n        perror(\"Erreur cr\u00e9ation socket\");\n        exit(EXIT_FAILURE);\n    }\n\n    \/* Configuration *\/\n    memset(&amp;adresse_serveur, 0, sizeof(adresse_serveur));\n    adresse_serveur.sin_family = AF_INET;\n    adresse_serveur.sin_addr.s_addr = INADDR_ANY;\n    adresse_serveur.sin_port = htons(PORT);\n\n    \/* Bind *\/\n    if (bind(serveur_fd, (struct sockaddr *)&amp;adresse_serveur, sizeof(adresse_serveur)) &lt; 0) {\n        perror(\"Erreur bind\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    \/* Listen *\/\n    if (listen(serveur_fd, 5) &lt; 0) {\n        perror(\"Erreur listen\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"Serveur HTTP en \u00e9coute sur le port %d\\n\", PORT);\n\n    while (1) {\n        client_fd = accept(serveur_fd, (struct sockaddr *)&amp;adresse_client, &amp;taille_client);\n        if (client_fd &lt; 0) {\n            perror(\"Erreur accept\");\n            continue;\n        }\n\n        printf(\"Client connect\u00e9 : %s:%d\\n\", \n               inet_ntoa(adresse_client.sin_addr), \n               ntohs(adresse_client.sin_port));\n\n        \/* Lire la requ\u00eate (optionnel, on ignore son contenu) *\/\n        bytes_lus = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);\n        if (bytes_lus > 0) {\n            buffer[bytes_lus] = '\\0';\n            printf(\"Requ\u00eate re\u00e7ue:\\n%s\\n\", buffer);\n            \n            \/* R\u00e9ponse simple *\/\n            if (strstr(buffer, \"GET \/ \") || strstr(buffer, \"GET \/index.html\")) {\n                send(client_fd, reponse_ok, strlen(reponse_ok), 0);\n                printf(\"R\u00e9ponse 200 OK envoy\u00e9e\\n\");\n            } else {\n                send(client_fd, reponse_404, strlen(reponse_404), 0);\n                printf(\"R\u00e9ponse 404 envoy\u00e9e\\n\");\n            }\n        }\n\n        close(client_fd);\n        printf(\"Connexion ferm\u00e9e\\n\\n\");\n    }\n\n    close(serveur_fd);\n    return 0;\n}<\/pre>\n\n\n\n<h2 id=\"serveur-http-multi-client\" class=\"wp-block-heading\">Serveur http multi-client<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;sys\/types.h>\n#include &lt;sys\/socket.h>\n#include &lt;sys\/wait.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n#include &lt;signal.h>\n#include &lt;time.h>\n\n#define PORT 8080\n#define BUFFER_SIZE 4096\n#define MAX_CLIENTS 100\n\nint clients_actifs = 0;\nint compteur_clients = 0;\n\nvoid gestionnaire_sigchld(int signo) {\n    while (waitpid(-1, NULL, WNOHANG) > 0) {\n        clients_actifs--;\n    }\n}\n\n\/* Envoyer une r\u00e9ponse HTTP *\/\nvoid envoyer_reponse_http(int client_fd, const char *body) {\n    char reponse[BUFFER_SIZE];\n    \n    sprintf(reponse,\n            \"HTTP\/1.1 200 OK\\r\\n\"\n            \"Content-Type: text\/html; charset=UTF-8\\r\\n\"\n            \"Content-Length: %ld\\r\\n\"\n            \"Connection: close\\r\\n\"\n            \"Server: ANSI-C\/1.0\\r\\n\"\n            \"\\r\\n\"\n            \"%s\",\n            strlen(body), body);\n    \n    send(client_fd, reponse, strlen(reponse), 0);\n}\n\n\/* Page d'accueil *\/\nvoid envoyer_accueil(int client_fd, int numero_client) {\n    char body[BUFFER_SIZE];\n    time_t now;\n    char date_str[64];\n    \n    time(&amp;now);\n    strftime(date_str, sizeof(date_str), \"%d\/%m\/%Y %H:%M:%S\", localtime(&amp;now));\n    \n    sprintf(body,\n            \"&lt;html>\\n\"\n            \"&lt;head>\\n\"\n            \"&lt;title>Serveur ANSI C&lt;\/title>\\n\"\n            \"&lt;\/head>\\n\"\n            \"&lt;body>\\n\"\n            \"&lt;h1>Serveur ANSI C&lt;\/h1>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;h2>Client numero : #%d&lt;\/h2>\\n\"\n            \"&lt;p>Clients actifs : %d&lt;\/p>\\n\"\n            \"&lt;p>Total clients servis : %d&lt;\/p>\\n\"\n            \"&lt;p>Date\/Heure : %s&lt;\/p>\\n\"\n            \"&lt;p>Port : %d | PID : %d&lt;\/p>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;p>&lt;a href='\/stats'>Voir les statistiques&lt;\/a>&lt;\/p>\\n\"\n            \"&lt;p>&lt;a href='\/quit'>Quitter&lt;\/a>&lt;\/p>\\n\"\n            \"&lt;\/body>\\n\"\n            \"&lt;\/html>\\n\",\n            numero_client, clients_actifs, compteur_clients, date_str, PORT, getpid());\n    \n    envoyer_reponse_http(client_fd, body);\n}\n\n\/* Page statistiques *\/\nvoid envoyer_stats(int client_fd, int numero_client) {\n    char body[BUFFER_SIZE];\n    \n    sprintf(body,\n            \"&lt;html>\\n\"\n            \"&lt;head>\\n\"\n            \"&lt;title>Statistiques&lt;\/title>\\n\"\n            \"&lt;\/head>\\n\"\n            \"&lt;body>\\n\"\n            \"&lt;h1>Statistiques&lt;\/h1>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;h2>Votre numero : #%d&lt;\/h2>\\n\"\n            \"&lt;p>Clients actuellement connectes : %d&lt;\/p>\\n\"\n            \"&lt;p>Total clients servis depuis demarrage : %d&lt;\/p>\\n\"\n            \"&lt;p>Capacite maximale : %d clients&lt;\/p>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;p>&lt;a href='\/'>Retour accueil&lt;\/a>&lt;\/p>\\n\"\n            \"&lt;\/body>\\n\"\n            \"&lt;\/html>\\n\",\n            numero_client, clients_actifs, compteur_clients, MAX_CLIENTS);\n    \n    envoyer_reponse_http(client_fd, body);\n}\n\n\/* Page 404 *\/\nvoid envoyer_404(int client_fd) {\n    char body[BUFFER_SIZE];\n    \n    sprintf(body,\n            \"&lt;html>\\n\"\n            \"&lt;head>\\n\"\n            \"&lt;title>404&lt;\/title>\\n\"\n            \"&lt;\/head>\\n\"\n            \"&lt;body>\\n\"\n            \"&lt;h1>404 - Page non trouvee&lt;\/h1>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;p>La page demandee n'existe pas.&lt;\/p>\\n\"\n            \"&lt;p>&lt;a href='\/'>Retour accueil&lt;\/a>&lt;\/p>\\n\"\n            \"&lt;\/body>\\n\"\n            \"&lt;\/html>\\n\");\n    \n    envoyer_reponse_http(client_fd, body);\n}\n\n\/* Page au revoir *\/\nvoid envoyer_au_revoir(int client_fd) {\n    char body[BUFFER_SIZE];\n    \n    sprintf(body,\n            \"&lt;html>\\n\"\n            \"&lt;head>\\n\"\n            \"&lt;title>Au revoir&lt;\/title>\\n\"\n            \"&lt;\/head>\\n\"\n            \"&lt;body>\\n\"\n            \"&lt;h1>Au revoir !&lt;\/h1>\\n\"\n            \"&lt;hr>\\n\"\n            \"&lt;p>Merci d'avoir visite notre serveur ANSI C.&lt;\/p>\\n\"\n            \"&lt;p>&lt;a href='\/'>Nouvelle connexion&lt;\/a>&lt;\/p>\\n\"\n            \"&lt;\/body>\\n\"\n            \"&lt;\/html>\\n\");\n    \n    envoyer_reponse_http(client_fd, body);\n}\n\n\/* Extraire le chemin de la requ\u00eate HTTP *\/\nvoid extraire_chemin(const char *requete, char *chemin) {\n    char method[16];\n    char path[256];\n    char version[16];\n    \n    sscanf(requete, \"%s %s %s\", method, path, version);\n    strcpy(chemin, path);\n}\n\nvoid traiter_client(int client_fd, struct sockaddr_in adresse_client, int numero_client) {\n    char buffer[BUFFER_SIZE];\n    int bytes_lus;\n    char chemin[256];\n    char client_ip[INET_ADDRSTRLEN];\n    \n    inet_ntop(AF_INET, &amp;adresse_client.sin_addr, client_ip, INET_ADDRSTRLEN);\n    \n    printf(\"[Client #%d] Connecte depuis %s:%d\\n\", \n           numero_client, client_ip, ntohs(adresse_client.sin_port));\n    \n    \/* Lire la requ\u00eate *\/\n    bytes_lus = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);\n    if (bytes_lus &lt;= 0) {\n        close(client_fd);\n        exit(0);\n    }\n    \n    buffer[bytes_lus] = '\\0';\n    extraire_chemin(buffer, chemin);\n    \n    printf(\"[Client #%d] Chemin: %s\\n\", numero_client, chemin);\n    \n    \/* Router selon le chemin *\/\n    if (strcmp(chemin, \"\/\") == 0 || strcmp(chemin, \"\/index.html\") == 0) {\n        envoyer_accueil(client_fd, numero_client);\n    }\n    else if (strcmp(chemin, \"\/stats\") == 0) {\n        envoyer_stats(client_fd, numero_client);\n    }\n    else if (strcmp(chemin, \"\/quit\") == 0) {\n        envoyer_au_revoir(client_fd);\n    }\n    else {\n        envoyer_404(client_fd);\n    }\n    \n    printf(\"[Client #%d] Deconnexion\\n\", numero_client);\n    close(client_fd);\n    exit(0);\n}\n\nint main(void) {\n    int serveur_fd, client_fd;\n    struct sockaddr_in adresse_serveur, adresse_client;\n    socklen_t taille_client = sizeof(adresse_client);\n    int opt = 1;\n    int numero_nouveau_client;\n    \n    \/* Gestion des signaux *\/\n    signal(SIGCHLD, gestionnaire_sigchld);\n    \n    \/* Cr\u00e9ation socket *\/\n    serveur_fd = socket(AF_INET, SOCK_STREAM, 0);\n    if (serveur_fd &lt; 0) {\n        perror(\"socket\");\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* Option reuse address *\/\n    setsockopt(serveur_fd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt));\n    \n    \/* Configuration adresse *\/\n    memset(&amp;adresse_serveur, 0, sizeof(adresse_serveur));\n    adresse_serveur.sin_family = AF_INET;\n    adresse_serveur.sin_addr.s_addr = INADDR_ANY;\n    adresse_serveur.sin_port = htons(PORT);\n    \n    \/* Bind *\/\n    if (bind(serveur_fd, (struct sockaddr *)&amp;adresse_serveur, sizeof(adresse_serveur)) &lt; 0) {\n        perror(\"bind\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n    \n    \/* Listen *\/\n    if (listen(serveur_fd, MAX_CLIENTS) &lt; 0) {\n        perror(\"listen\");\n        close(serveur_fd);\n        exit(EXIT_FAILURE);\n    }\n    \n    printf(\"\\n========================================\\n\");\n    printf(\"SERVEUR HTTP ANSI C\\n\");\n    printf(\"========================================\\n\");\n    printf(\"Port: %d\\n\", PORT);\n    printf(\"URL: http:\/\/localhost:%d\/\\n\", PORT);\n    printf(\"PID: %d\\n\", getpid());\n    printf(\"========================================\\n\\n\");\n    \n    \/* Boucle principale *\/\n    while (1) {\n        client_fd = accept(serveur_fd, (struct sockaddr *)&amp;adresse_client, &amp;taille_client);\n        if (client_fd &lt; 0) {\n            perror(\"accept\");\n            continue;\n        }\n        \n        clients_actifs++;\n        compteur_clients++;\n        numero_nouveau_client = compteur_clients;\n        \n        printf(\"[SERVEUR] +++ Client #%d connecte (Actifs: %d) +++\\n\", \n               numero_nouveau_client, clients_actifs);\n        \n        {\n            pid_t pid = fork();\n            \n            if (pid == 0) {\n                \/* Processus fils *\/\n                close(serveur_fd);\n                traiter_client(client_fd, adresse_client, numero_nouveau_client);\n                exit(0);\n            } else if (pid > 0) {\n                \/* Processus p\u00e8re *\/\n                close(client_fd);\n            } else {\n                perror(\"fork\");\n                clients_actifs--;\n                close(client_fd);\n            }\n        }\n    }\n    \n    close(serveur_fd);\n    return 0;\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Serveur TCP Makefile Client TCP Makefile Muti_serveur (fork) Serveur http Serveur http multi-client<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"{\"document\":\"AAAH0sfe\/xLQBNoBCAwDABSC5QYABgIBAgoBEEoANAECCgJCAQ1KAIoCAQIKAQ9KMAIBAgoCQgENSgCyAQECCgJCAQ1KALYCAQIKAkIBDUoAjgIBAgoCQgENSugHiAoBAgoCQgEPSgCKAQECCgEVSgA+AQIKAkIBD0oAhAEBAgoBFUoAPgECCgJCAQ9KAIgBAQIKARVKAD4BAgoCQgEPSgCEAQECCgEVSgA+AQIKAkIBD0oAmgEBAgoBFUoAPgECCgJCAQ9KAI4BAQIKARVKAD4BAgoCQgEPSgCmAQECCgEVSsCBBwAEGoCCB4MCKAMnAAQAhAInAAQAJwAoBCcAKAEnAAcAKAMnACgSJwCHACgDJwEEACgPJwCHACgDJwAoEScABwAoAycBBAAoDycAhwAoAycBBAAoDycAhwAoAycBBAAoDycAhwAoAycBBAAoDycAhwAoAycBBAAoEScAhwAoAycAKBcnAIcAKAMnAQQAKBEnAIcAKAMnACgXJwCHACgDJwEEACgRJwCHACgDJwAoFycAhwAoAycBBAAoEScAhwAoAycAKBcnAIcAKAMnAQQAKBEnAIcAKAMnACgXJwCHACgDJwEEACgRJwCHACgDJwAoFycAhwAoAycBBAAoEScAhwAoAycAKBcnACgBxNyXAv2SAnN0YXRldmVyc2lvbmRvY3VtZW50ZGF0ZWRvY3VtZW50c2x1Z2RvY3VtZW50c3RhdHVzZG9jdW1lbnR0aXRsZVNvY2tldHMgZW4gQyBhbnNpZG9jdW1lbnRjb250ZW50PCEtLSB3cDp0YWJsZS1vZi1jb250ZW50cyB7ImhlYWRpbmdzIjpbeyJjb250ZW50IjoiU2VydmV1ciBUQ1AiLCJsZXZlbCI6MiwibGluayI6Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI3NlcnZldXItdGNwIn0seyJjb250ZW50IjoiTWFrZWZpbGUiLCJsZXZlbCI6MywibGluayI6Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI21ha2VmaWxlIn0seyJjb250ZW50IjoiQ2xpZW50IFRDUCIsImxldmVsIjoyLCJsaW5rIjoiaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jY2xpZW50LXRjcCJ9LHsiY29udGVudCI6Ik1ha2VmaWxlIiwibGV2ZWwiOjMsImxpbmsiOiJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNtYWtlZmlsZS0xIn0seyJjb250ZW50IjoiTXV0aV9zZXJ2ZXVyIChmb3JrKSIsImxldmVsIjoyLCJsaW5rIjoiaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jbXV0aS1zZXJ2ZXVyLWZvcmsifSx7ImNvbnRlbnQiOiJTZXJ2ZXVyIGh0dHAgIiwibGV2ZWwiOjIsImxpbmsiOiJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNzZXJ2ZXVyLWh0dHAifSx7ImNvbnRlbnQiOiJTZXJ2ZXVyIGh0dHAgbXVsdGktY2xpZW50IiwibGV2ZWwiOjIsImxpbmsiOiJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNzZXJ2ZXVyLWh0dHAtbXVsdGktY2xpZW50In1dfSAtLT4KPG5hdiBjbGFzcz0id3AtYmxvY2stdGFibGUtb2YtY29udGVudHMiPjxvbD48bGk+PGEgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzX19lbnRyeSIgaHJlZj0iaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jc2VydmV1ci10Y3AiPlNlcnZldXIgVENQPC9hPjxvbD48bGk+PGEgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzX19lbnRyeSIgaHJlZj0iaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jbWFrZWZpbGUiPk1ha2VmaWxlPC9hPjwvbGk+PC9vbD48L2xpPjxsaT48YSBjbGFzcz0id3AtYmxvY2stdGFibGUtb2YtY29udGVudHNfX2VudHJ5IiBocmVmPSJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNjbGllbnQtdGNwIj5DbGllbnQgVENQPC9hPjxvbD48bGk+PGEgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzX19lbnRyeSIgaHJlZj0iaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jbWFrZWZpbGUtMSI+TWFrZWZpbGU8L2E+PC9saT48L29sPjwvbGk+PGxpPjxhIGNsYXNzPSJ3cC1ibG9jay10YWJsZS1vZi1jb250ZW50c19fZW50cnkiIGhyZWY9Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI211dGktc2VydmV1ci1mb3JrIj5NdXRpX3NlcnZldXIgKGZvcmspPC9hPjwvbGk+PGxpPjxhIGNsYXNzPSJ3cC1ibG9jay10YWJsZS1vZi1jb250ZW50c19fZW50cnkiIGhyZWY9Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI3NlcnZldXItaHR0cCI+U2VydmV1ciBodHRwIDwvYT48L2xpPjxsaT48YSBjbGFzcz0id3AtYmxvY2stdGFibGUtb2YtY29udGVudHNfX2VudHJ5IiBocmVmPSJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNzZXJ2ZXVyLWh0dHAtbXVsdGktY2xpZW50Ij5TZXJ2ZXVyIGh0dHAgbXVsdGktY2xpZW50PC9hPjwvbGk+PC9vbD48L25hdj4KPCEtLSAvd3A6dGFibGUtb2YtY29udGVudHMgLS0+Cgo8IS0tIHdwOmNvZGUgLS0+CjxwcmUgY2xhc3M9IndwLWJsb2NrLWNvZGUiPjxjb2RlPnNlcnZldXJfZmQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApCjwvY29kZT48L3ByZT4KPCEtLSAvd3A6Y29kZSAtLT4KCjwhLS0gd3A6bGlzdCAtLT4KPHVsIGNsYXNzPSJ3cC1ibG9jay1saXN0Ij48IS0tIHdwOmxpc3QtaXRlbSAtLT4KPGxpPkFGX0lORVQgOiBGYW1pbGxlIGQnYWRyZXNzZXMgSVB2NDwvbGk+CjwhLS0gL3dwOmxpc3QtaXRlbSAtLT4KCjwhLS0gd3A6bGlzdC1pdGVtIC0tPgo8bGk+U09DS19TVFJFQU0gOiBUeXBlIGRlIHNvY2tldCAoVENQLCBmaWFibGUsIGNvbm5leGlvbiBvcmllbnTDqWUgZmx1eCk8L2xpPgo8IS0tIC93cDpsaXN0LWl0ZW0gLS0+Cgo8IS0tIHdwOmxpc3QtaXRlbSAtLT4KPGxpPjAgOiBQcm90b2NvbGUgcGFyIGTDqWZhdXQgKFRDUCBwb3VyIFNPQ0tfU1RSRUFNKTwvbGk+CjwhLS0gL3dwOmxpc3QtaXRlbSAtLT4KCjwhLS0gd3A6bGlzdC1pdGVtIC0tPgo8bGk+UmV0b3VyIDogRGVzY3JpcHRldXIgZGUgZmljaGllciAoZW50aWVyKSBvdSAtMSBzaSBlcnJldXI8L2xpPgo8IS0tIC93cDpsaXN0LWl0ZW0gLS0+PC91bD4KPCEtLSAvd3A6bGlzdCAtLT4KCjwhLS0gd3A6aGVhZGluZyB7ImFuY2hvciI6InNlcnZldXItdGNwIn0gLS0+CjxoMiBpZD0ic2VydmV1ci10Y3AiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5TZXJ2ZXVyIFRDUDwvaDI+CjwhLS0gL3dwOmhlYWRpbmcgLS0+Cgo8IS0tIHdwOmVubGlnaHRlci9jb2RlYmxvY2sgeyJsYW5ndWFnZSI6ImMifSAtLT4KPHByZSBjbGFzcz0iRW5saWdodGVySlNSQVciIGRhdGEtZW5saWdodGVyLWxhbmd1YWdlPSJjIiBkYXRhLWVubGlnaHRlci10aGVtZT0iIiBkYXRhLWVubGlnaHRlci1oaWdobGlnaHQ9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW51bWJlcnM9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW9mZnNldD0iIiBkYXRhLWVubGlnaHRlci10aXRsZT0iIiBkYXRhLWVubGlnaHRlci1ncm91cD0iIj4jaW5jbHVkZSAmbHQ7c3RkaW8uaD4KI2luY2x1ZGUgJmx0O3N0ZGxpYi5oPgojaW5jbHVkZSAmbHQ7c3RyaW5nLmg+CiNpbmNsdWRlICZsdDt1bmlzdGQuaD4KI2luY2x1ZGUgJmx0O3N5cy90eXBlcy5oPgojaW5jbHVkZSAmbHQ7c3lzL3NvY2tldC5oPgojaW5jbHVkZSAmbHQ7bmV0aW5ldC9pbi5oPgojaW5jbHVkZSAmbHQ7YXJwYS9pbmV0Lmg+CiNpbmNsdWRlICZsdDtuZXRkYi5oPgoKI2RlZmluZSBQT1JUIDg4ODgKI2RlZmluZSBCVUZGRVJfU0laRSAxMDI0CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CiAgICBpbnQgc29ja19mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXI7CiAgICBzdHJ1Y3QgaG9zdGVudCAqc2VydmV1cjsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGNoYXIgbWVzc2FnZVtCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfcmVjdXM7CiAgICBzdHJ1Y3QgaW5fYWRkciAqKmFkZHJfbGlzdDsgIC8qIFBvdXIgdW5lIHZlcnNpb24gcGx1cyBleHBsaWNpdGUgKi8KCiAgICAvKiBWw6lyaWZpY2F0aW9uIGRlcyBhcmd1bWVudHMgKi8KICAgIGlmIChhcmdjICZsdDsgMikgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6ICVzICZsdDthZHJlc3NlX3NlcnZldXI+XG4iLCBhcmd2WzBdKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMS4gQ3LDqWF0aW9uIGR1IHNvY2tldCAqLwogICAgc29ja19mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc29ja19mZCAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjcsOpYXRpb24gc29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDIuIFLDqXNvbHV0aW9uIGR1IG5vbSBkJ2jDtHRlICovCiAgICBzZXJ2ZXVyID0gZ2V0aG9zdGJ5bmFtZShhcmd2WzFdKTsKICAgIGlmIChzZXJ2ZXVyID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkjDtHRlIGluY29ubnUgOiAlc1xuIiwgYXJndlsxXSk7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDMuIENvbmZpZ3VyYXRpb24gZGUgbCdhZHJlc3NlICovCiAgICBtZW1zZXQoJmFtcDthZHJlc3NlX3NlcnZldXIsIDAsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIAogICAgLyogTcOpdGhvZGUgYWx0ZXJuYXRpdmUgcGx1cyBleHBsaWNpdGUgKi8KICAgIGFkZHJfbGlzdCA9IChzdHJ1Y3QgaW5fYWRkciAqKilzZXJ2ZXVyLT5oX2FkZHJfbGlzdDsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkciA9ICphZGRyX2xpc3RbMF07CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX3BvcnQgPSBodG9ucyhQT1JUKTsKCiAgICAvKiA0LiBDb25uZXhpb24gYXUgc2VydmV1ciAqLwogICAgaWYgKGNvbm5lY3Qoc29ja19mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSkgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgY29ubmVjdCIpOwogICAgICAgIGNsb3NlKHNvY2tfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KCiAgICBwcmludGYoIkNvbm5lY3TDqSBhdSBzZXJ2ZXVyICVzOiVkXG4iLCBhcmd2WzFdLCBQT1JUKTsKICAgIHByaW50ZigiQWRyZXNzZSBJUCA6ICVzXG4iLCBpbmV0X250b2EoYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyKSk7CgogICAgLyogNS4gw4ljaGFuZ2UgZGUgZG9ubsOpZXMgKi8KICAgIHdoaWxlICgxKSB7CiAgICAgICAgcHJpbnRmKCJNZXNzYWdlIMOgIGVudm95ZXIgKG91ICdxdWl0JyBwb3VyIHF1aXR0ZXIpIDogIik7CiAgICAgICAgZmdldHMobWVzc2FnZSwgQlVGRkVSX1NJWkUsIHN0ZGluKTsKICAgICAgICAKICAgICAgICAvKiBTdXBwcmVzc2lvbiBkdSBzYXV0IGRlIGxpZ25lICovCiAgICAgICAgbWVzc2FnZVtzdHJjc3BuKG1lc3NhZ2UsICJcbiIpXSA9ICdcMCc7CiAgICAgICAgCiAgICAgICAgaWYgKHN0cmNtcChtZXNzYWdlLCAicXVpdCIpID09IDApIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8qIEVudm9pICovCiAgICAgICAgc2VuZChzb2NrX2ZkLCBtZXNzYWdlLCBzdHJsZW4obWVzc2FnZSksIDApOwogICAgICAgIAogICAgICAgIC8qIFLDqWNlcHRpb24gZGUgbGEgcsOpcG9uc2UgKi8KICAgICAgICBieXRlc19yZWN1cyA9IHJlY3Yoc29ja19mZCwgYnVmZmVyLCBCVUZGRVJfU0laRSAtIDEsIDApOwogICAgICAgIGlmIChieXRlc19yZWN1cyAmbHQ7PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiU2VydmV1ciBkw6ljb25uZWN0w6lcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYnVmZmVyW2J5dGVzX3JlY3VzXSA9ICdcMCc7CiAgICAgICAgcHJpbnRmKCJSw6lwb25zZSBkdSBzZXJ2ZXVyIDogJXNcbiIsIGJ1ZmZlcik7CiAgICB9CgogICAgLyogNi4gRmVybWV0dXJlICovCiAgICBjbG9zZShzb2NrX2ZkKTsKICAgIHJldHVybiAwOwp9PC9wcmU+CjwhLS0gL3dwOmVubGlnaHRlci9jb2RlYmxvY2sgLS0+Cgo8IS0tIHdwOmhlYWRpbmcgeyJsZXZlbCI6MywiYW5jaG9yIjoibWFrZWZpbGUifSAtLT4KPGgzIGlkPSJtYWtlZmlsZSIgY2xhc3M9IndwLWJsb2NrLWhlYWRpbmciPk1ha2VmaWxlPC9oMz4KPCEtLSAvd3A6aGVhZGluZyAtLT4KCjwhLS0gd3A6ZW5saWdodGVyL2NvZGVibG9jayB7Imxhbmd1YWdlIjoibWQifSAtLT4KPHByZSBjbGFzcz0iRW5saWdodGVySlNSQVciIGRhdGEtZW5saWdodGVyLWxhbmd1YWdlPSJtZCIgZGF0YS1lbmxpZ2h0ZXItdGhlbWU9IiIgZGF0YS1lbmxpZ2h0ZXItaGlnaGxpZ2h0PSIiIGRhdGEtZW5saWdodGVyLWxpbmVudW1iZXJzPSIiIGRhdGEtZW5saWdodGVyLWxpbmVvZmZzZXQ9IiIgZGF0YS1lbmxpZ2h0ZXItdGl0bGU9IiIgZGF0YS1lbmxpZ2h0ZXItZ3JvdXA9IiI+Q0MgPSBnY2MKQ0ZMQUdTID0gLVdhbGwgLVdleHRyYSAtYW5zaSAtcGVkYW50aWMKCmFsbDogc2VydmV1cgoKc2VydmV1cjogc2VydmV1cl90Y3AuYwoJJChDQykgJChDRkxBR1MpIC1vIHNlcnZldXIgc2VydmV1cl90Y3AuYwoKY2xlYW46CglybSAtZiBzZXJ2ZXVyCgouUEhPTlk6IGFsbCBjbGVhbgo8L3ByZT4KPCEtLSAvd3A6ZW5saWdodGVyL2NvZGVibG9jayAtLT4KCjwhLS0gd3A6aGVhZGluZyB7ImFuY2hvciI6ImNsaWVudC10Y3AifSAtLT4KPGgyIGlkPSJjbGllbnQtdGNwIiBjbGFzcz0id3AtYmxvY2staGVhZGluZyI+Q2xpZW50IFRDUDwvaDI+CjwhLS0gL3dwOmhlYWRpbmcgLS0+Cgo8IS0tIHdwOmVubGlnaHRlci9jb2RlYmxvY2sgeyJsYW5ndWFnZSI6ImMifSAtLT4KPHByZSBjbGFzcz0iRW5saWdodGVySlNSQVciIGRhdGEtZW5saWdodGVyLWxhbmd1YWdlPSJjIiBkYXRhLWVubGlnaHRlci10aGVtZT0iIiBkYXRhLWVubGlnaHRlci1oaWdobGlnaHQ9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW51bWJlcnM9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW9mZnNldD0iIiBkYXRhLWVubGlnaHRlci10aXRsZT0iIiBkYXRhLWVubGlnaHRlci1ncm91cD0iIj4jaW5jbHVkZSAmbHQ7c3RkaW8uaD4KI2luY2x1ZGUgJmx0O3N0ZGxpYi5oPgojaW5jbHVkZSAmbHQ7c3RyaW5nLmg+CiNpbmNsdWRlICZsdDt1bmlzdGQuaD4KI2luY2x1ZGUgJmx0O3N5cy90eXBlcy5oPgojaW5jbHVkZSAmbHQ7c3lzL3NvY2tldC5oPgojaW5jbHVkZSAmbHQ7bmV0aW5ldC9pbi5oPgojaW5jbHVkZSAmbHQ7YXJwYS9pbmV0Lmg+CiNpbmNsdWRlICZsdDtuZXRkYi5oPgoKI2RlZmluZSBQT1JUIDg4ODgKI2RlZmluZSBCVUZGRVJfU0laRSAxMDI0CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CiAgICBpbnQgc29ja19mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXI7CiAgICBzdHJ1Y3QgaG9zdGVudCAqc2VydmV1cjsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGNoYXIgbWVzc2FnZVtCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfcmVjdXM7CiAgICBzdHJ1Y3QgaW5fYWRkciAqKmFkZHJfbGlzdDsgIC8qIFBvdXIgdW5lIHZlcnNpb24gcGx1cyBleHBsaWNpdGUgKi8KCiAgICAvKiBWw6lyaWZpY2F0aW9uIGRlcyBhcmd1bWVudHMgKi8KICAgIGlmIChhcmdjICZsdDsgMikgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6ICVzICZsdDthZHJlc3NlX3NlcnZldXI+XG4iLCBhcmd2WzBdKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMS4gQ3LDqWF0aW9uIGR1IHNvY2tldCAqLwogICAgc29ja19mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc29ja19mZCAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjcsOpYXRpb24gc29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDIuIFLDqXNvbHV0aW9uIGR1IG5vbSBkJ2jDtHRlICovCiAgICBzZXJ2ZXVyID0gZ2V0aG9zdGJ5bmFtZShhcmd2WzFdKTsKICAgIGlmIChzZXJ2ZXVyID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkjDtHRlIGluY29ubnUgOiAlc1xuIiwgYXJndlsxXSk7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDMuIENvbmZpZ3VyYXRpb24gZGUgbCdhZHJlc3NlICovCiAgICBtZW1zZXQoJmFtcDthZHJlc3NlX3NlcnZldXIsIDAsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIAogICAgLyogTcOpdGhvZGUgYWx0ZXJuYXRpdmUgcGx1cyBleHBsaWNpdGUgKi8KICAgIGFkZHJfbGlzdCA9IChzdHJ1Y3QgaW5fYWRkciAqKilzZXJ2ZXVyLT5oX2FkZHJfbGlzdDsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkciA9ICphZGRyX2xpc3RbMF07CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX3BvcnQgPSBodG9ucyhQT1JUKTsKCiAgICAvKiA0LiBDb25uZXhpb24gYXUgc2VydmV1ciAqLwogICAgaWYgKGNvbm5lY3Qoc29ja19mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSkgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgY29ubmVjdCIpOwogICAgICAgIGNsb3NlKHNvY2tfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KCiAgICBwcmludGYoIkNvbm5lY3TDqSBhdSBzZXJ2ZXVyICVzOiVkXG4iLCBhcmd2WzFdLCBQT1JUKTsKICAgIHByaW50ZigiQWRyZXNzZSBJUCA6ICVzXG4iLCBpbmV0X250b2EoYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyKSk7CgogICAgLyogNS4gw4ljaGFuZ2UgZGUgZG9ubsOpZXMgKi8KICAgIHdoaWxlICgxKSB7CiAgICAgICAgcHJpbnRmKCJNZXNzYWdlIMOgIGVudm95ZXIgKG91ICdxdWl0JyBwb3VyIHF1aXR0ZXIpIDogIik7CiAgICAgICAgZmdldHMobWVzc2FnZSwgQlVGRkVSX1NJWkUsIHN0ZGluKTsKICAgICAgICAKICAgICAgICAvKiBTdXBwcmVzc2lvbiBkdSBzYXV0IGRlIGxpZ25lICovCiAgICAgICAgbWVzc2FnZVtzdHJjc3BuKG1lc3NhZ2UsICJcbiIpXSA9ICdcMCc7CiAgICAgICAgCiAgICAgICAgaWYgKHN0cmNtcChtZXNzYWdlLCAicXVpdCIpID09IDApIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8qIEVudm9pICovCiAgICAgICAgc2VuZChzb2NrX2ZkLCBtZXNzYWdlLCBzdHJsZW4obWVzc2FnZSksIDApOwogICAgICAgIAogICAgICAgIC8qIFLDqWNlcHRpb24gZGUgbGEgcsOpcG9uc2UgKi8KICAgICAgICBieXRlc19yZWN1cyA9IHJlY3Yoc29ja19mZCwgYnVmZmVyLCBCVUZGRVJfU0laRSAtIDEsIDApOwogICAgICAgIGlmIChieXRlc19yZWN1cyAmbHQ7PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiU2VydmV1ciBkw6ljb25uZWN0w6lcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYnVmZmVyW2J5dGVzX3JlY3VzXSA9ICdcMCc7CiAgICAgICAgcHJpbnRmKCJSw6lwb25zZSBkdSBzZXJ2ZXVyIDogJXNcbiIsIGJ1ZmZlcik7CiAgICB9CgogICAgLyogNi4gRmVybWV0dXJlICovCiAgICBjbG9zZShzb2NrX2ZkKTsKICAgIHJldHVybiAwOwp9PC9wcmU+CjwhLS0gL3dwOmVubGlnaHRlci9jb2RlYmxvY2sgLS0+Cgo8IS0tIHdwOmhlYWRpbmcgeyJsZXZlbCI6MywiYW5jaG9yIjoibWFrZWZpbGUtMSJ9IC0tPgo8aDMgaWQ9Im1ha2VmaWxlLTEiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5NYWtlZmlsZTwvaDM+CjwhLS0gL3dwOmhlYWRpbmcgLS0+Cgo8IS0tIHdwOmVubGlnaHRlci9jb2RlYmxvY2sgeyJsYW5ndWFnZSI6Im1kIn0gLS0+CjxwcmUgY2xhc3M9IkVubGlnaHRlckpTUkFXIiBkYXRhLWVubGlnaHRlci1sYW5ndWFnZT0ibWQiIGRhdGEtZW5saWdodGVyLXRoZW1lPSIiIGRhdGEtZW5saWdodGVyLWhpZ2hsaWdodD0iIiBkYXRhLWVubGlnaHRlci1saW5lbnVtYmVycz0iIiBkYXRhLWVubGlnaHRlci1saW5lb2Zmc2V0PSIiIGRhdGEtZW5saWdodGVyLXRpdGxlPSIiIGRhdGEtZW5saWdodGVyLWdyb3VwPSIiPkNDID0gZ2NjCkNGTEFHUyA9IC1XYWxsIC1XZXh0cmEgLWFuc2kgLXBlZGFudGljCgphbGw6IGNsaWVudAoKY2xpZW50OiBjbGllbnRfdGNwLmMKCSQoQ0MpICQoQ0ZMQUdTKSAtbyBjbGllbnQgY2xpZW50X3RjcC5jCgpjbGVhbjoKCXJtIC1mIGNsaWVudAoKLlBIT05ZOiBhbGwgY2xlYW4KPC9wcmU+CjwhLS0gL3dwOmVubGlnaHRlci9jb2RlYmxvY2sgLS0+Cgo8IS0tIHdwOmhlYWRpbmcgeyJhbmNob3IiOiJtdXRpLXNlcnZldXItZm9yayJ9IC0tPgo8aDIgaWQ9Im11dGktc2VydmV1ci1mb3JrIiBjbGFzcz0id3AtYmxvY2staGVhZGluZyI+TXV0aV9zZXJ2ZXVyIChmb3JrKTwvaDI+CjwhLS0gL3dwOmhlYWRpbmcgLS0+Cgo8IS0tIHdwOmVubGlnaHRlci9jb2RlYmxvY2sgLS0+CjxwcmUgY2xhc3M9IkVubGlnaHRlckpTUkFXIiBkYXRhLWVubGlnaHRlci1sYW5ndWFnZT0iZ2VuZXJpYyIgZGF0YS1lbmxpZ2h0ZXItdGhlbWU9IiIgZGF0YS1lbmxpZ2h0ZXItaGlnaGxpZ2h0PSIiIGRhdGEtZW5saWdodGVyLWxpbmVudW1iZXJzPSIiIGRhdGEtZW5saWdodGVyLWxpbmVvZmZzZXQ9IiIgZGF0YS1lbmxpZ2h0ZXItdGl0bGU9IiIgZGF0YS1lbmxpZ2h0ZXItZ3JvdXA9IiI+I2luY2x1ZGUgJmx0O3N0ZGlvLmg+CiNpbmNsdWRlICZsdDtzdGRsaWIuaD4KI2luY2x1ZGUgJmx0O3N0cmluZy5oPgojaW5jbHVkZSAmbHQ7dW5pc3RkLmg+CiNpbmNsdWRlICZsdDtzeXMvdHlwZXMuaD4KI2luY2x1ZGUgJmx0O3N5cy9zb2NrZXQuaD4KI2luY2x1ZGUgJmx0O3N5cy93YWl0Lmg+CiNpbmNsdWRlICZsdDtuZXRpbmV0L2luLmg+CiNpbmNsdWRlICZsdDthcnBhL2luZXQuaD4KI2luY2x1ZGUgJmx0O3NpZ25hbC5oPgoKI2RlZmluZSBQT1JUIDg4ODgKI2RlZmluZSBCVUZGRVJfU0laRSAxMDI0CiNkZWZpbmUgTUFYX0NMSUVOVFMgMTAKCi8qIEdlc3Rpb25uYWlyZSBkZSBzaWduYXV4IHBvdXIgw6l2aXRlciBsZXMgcHJvY2Vzc3VzIHpvbWJpZXMgKi8Kdm9pZCBnZXN0aW9ubmFpcmVfc2lnY2hsZChpbnQgc2lnbm8pIHsKICAgIC8qIHdhaXRwaWQgYXZlYyBXTk9IQU5HIHBvdXIgbmUgcGFzIGJsb3F1ZXIgKi8KICAgIHdoaWxlICh3YWl0cGlkKC0xLCBOVUxMLCBXTk9IQU5HKSA+IDApOwp9CgovKiBGb25jdGlvbiBwb3VyIHRyYWl0ZXIgY2hhcXVlIGNsaWVudCAqLwp2b2lkIHRyYWl0ZXJfY2xpZW50KGludCBjbGllbnRfZmQsIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX2NsaWVudCkgewogICAgY2hhciBidWZmZXJbQlVGRkVSX1NJWkVdOwogICAgaW50IGJ5dGVzX2x1czsKICAgIGludCBpOwogICAgY2hhciBjbGllbnRfaXBbSU5FVF9BRERSU1RSTEVOXTsKICAgIAogICAgLyogQ29udmVydGlyIGwnYWRyZXNzZSBJUCBlbiBjaGHDrm5lICovCiAgICBpbmV0X250b3AoQUZfSU5FVCwgJmFtcDthZHJlc3NlX2NsaWVudC5zaW5fYWRkciwgY2xpZW50X2lwLCBJTkVUX0FERFJTVFJMRU4pOwogICAgcHJpbnRmKCJbUHJvY2Vzc3VzICVkXSBDbGllbnQgY29ubmVjdMOpIDogJXM6JWRcbiIsIAogICAgICAgICAgIGdldHBpZCgpLCAKICAgICAgICAgICBjbGllbnRfaXAsIAogICAgICAgICAgIG50b2hzKGFkcmVzc2VfY2xpZW50LnNpbl9wb3J0KSk7CiAgICAKICAgIC8qIENvbW11bmljYXRpb24gYXZlYyBsZSBjbGllbnQgKi8KICAgIHdoaWxlICgoYnl0ZXNfbHVzID0gcmVjdihjbGllbnRfZmQsIGJ1ZmZlciwgQlVGRkVSX1NJWkUgLSAxLCAwKSkgPiAwKSB7CiAgICAgICAgYnVmZmVyW2J5dGVzX2x1c10gPSAnXDAnOwogICAgICAgIHByaW50ZigiW1Byb2Nlc3N1cyAlZF0gUmXDp3UgOiAlcyIsIGdldHBpZCgpLCBidWZmZXIpOwogICAgICAgIAogICAgICAgIC8qIENvbnZlcnNpb24gZW4gbWFqdXNjdWxlcyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgJmx0OyBieXRlc19sdXM7IGkrKykgewogICAgICAgICAgICBpZiAoYnVmZmVyW2ldID49ICdhJyAmYW1wOyZhbXA7IGJ1ZmZlcltpXSAmbHQ7PSAneicpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcltpXSA9IGJ1ZmZlcltpXSAtICdhJyArICdBJzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKiBFbnZvaSBkZSBsYSByw6lwb25zZSAqLwogICAgICAgIHNlbmQoY2xpZW50X2ZkLCBidWZmZXIsIGJ5dGVzX2x1cywgMCk7CiAgICB9CiAgICAKICAgIGlmIChieXRlc19sdXMgPT0gMCkgewogICAgICAgIHByaW50ZigiW1Byb2Nlc3N1cyAlZF0gQ2xpZW50IGTDqWNvbm5lY3TDqVxuIiwgZ2V0cGlkKCkpOwogICAgfSBlbHNlIHsKICAgICAgICBwZXJyb3IoIltQcm9jZXNzdXMgJWRdIEVycmV1ciByZWN2Iik7CiAgICB9CiAgICAKICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICBwcmludGYoIltQcm9jZXNzdXMgJWRdIENvbm5leGlvbiBmZXJtw6llLCBwcm9jZXNzdXMgdGVybWluZVxuIiwgZ2V0cGlkKCkpOwogICAgZXhpdCgwKTsgIC8qIExlIHByb2Nlc3N1cyBmaWxzIHNlIHRlcm1pbmUgKi8KfQoKaW50IG1haW4odm9pZCkgewogICAgaW50IHNlcnZldXJfZmQsIGNsaWVudF9mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXIsIGFkcmVzc2VfY2xpZW50OwogICAgc29ja2xlbl90IHRhaWxsZV9jbGllbnQgPSBzaXplb2YoYWRyZXNzZV9jbGllbnQpOwogICAgc3RydWN0IHNpZ2FjdGlvbiBzYTsKICAgIGludCBvcHQgPSAxOwogICAgCiAgICAvKiAxLiBDb25maWd1cmF0aW9uIGR1IGdlc3Rpb25uYWlyZSBkZSBzaWduYXV4IHBvdXIgw6l2aXRlciBsZXMgem9tYmllcyAqLwogICAgc2Euc2FfaGFuZGxlciA9IGdlc3Rpb25uYWlyZV9zaWdjaGxkOwogICAgc2lnZW1wdHlzZXQoJmFtcDtzYS5zYV9tYXNrKTsKICAgIHNhLnNhX2ZsYWdzID0gU0FfUkVTVEFSVDsgIC8qIFLDqWluaXRpYWxpc2VyIGxlcyBhcHBlbHMgc3lzdMOobWUgaW50ZXJyb21wdXMgKi8KICAgIGlmIChzaWdhY3Rpb24oU0lHQ0hMRCwgJmFtcDtzYSwgTlVMTCkgPT0gLTEpIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBzaWdhY3Rpb24iKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIDIuIENyw6lhdGlvbiBkdSBzb2NrZXQgKi8KICAgIHNlcnZldXJfZmQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApOwogICAgaWYgKHNlcnZldXJfZmQgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgY3LDqWF0aW9uIHNvY2tldCIpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogMy4gT3B0aW9uIHBvdXIgcsOpdXRpbGlzZXIgbCdhZHJlc3NlICjDqXZpdGUgIkFkZHJlc3MgYWxyZWFkeSBpbiB1c2UiKSAqLwogICAgaWYgKHNldHNvY2tvcHQoc2VydmV1cl9mZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAmYW1wO29wdCwgc2l6ZW9mKG9wdCkpICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIHNldHNvY2tvcHQiKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIDQuIENvbmZpZ3VyYXRpb24gZGUgbCdhZHJlc3NlIGR1IHNlcnZldXIgKi8KICAgIG1lbXNldCgmYW1wO2FkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyLnNfYWRkciA9IElOQUREUl9BTlk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX3BvcnQgPSBodG9ucyhQT1JUKTsKICAgIAogICAgLyogNS4gQXR0YWNoZW1lbnQgZHUgc29ja2V0ICovCiAgICBpZiAoYmluZChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBiaW5kIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiA2LiBNaXNlIGVuIMOpY291dGUgKi8KICAgIGlmIChsaXN0ZW4oc2VydmV1cl9mZCwgTUFYX0NMSUVOVFMpICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGxpc3RlbiIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgcHJpbnRmKCJTZXJ2ZXVyIG11bHRpLWNsaWVudHMgZMOpbWFycsOpIHN1ciBsZSBwb3J0ICVkXG4iLCBQT1JUKTsKICAgIHByaW50ZigiUElEIGR1IHNlcnZldXIgcHJpbmNpcGFsIDogJWRcbiIsIGdldHBpZCgpKTsKICAgIHByaW50ZigiRW4gYXR0ZW50ZSBkZSBjb25uZXhpb25zLi4uXG5cbiIpOwogICAgCiAgICAvKiA3LiBCb3VjbGUgcHJpbmNpcGFsZSBkJ2FjY2VwdGF0aW9uICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIC8qIEFjY2VwdGVyIHVuZSBub3V2ZWxsZSBjb25uZXhpb24gKi8KICAgICAgICBjbGllbnRfZmQgPSBhY2NlcHQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9jbGllbnQsICZhbXA7dGFpbGxlX2NsaWVudCk7CiAgICAgICAgaWYgKGNsaWVudF9mZCAmbHQ7IDApIHsKICAgICAgICAgICAgcGVycm9yKCJFcnJldXIgYWNjZXB0Iik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKiBDcsOpYXRpb24gZCd1biBwcm9jZXNzdXMgZmlscyBwb3VyIGfDqXJlciBsZSBjbGllbnQgKi8KICAgICAgICBwaWRfdCBwaWQgPSBmb3JrKCk7CiAgICAgICAgCiAgICAgICAgaWYgKHBpZCAmbHQ7IDApIHsKICAgICAgICAgICAgcGVycm9yKCJFcnJldXIgZm9yayIpOwogICAgICAgICAgICBjbG9zZShjbGllbnRfZmQpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKHBpZCA9PSAwKSB7CiAgICAgICAgICAgIC8qIFByb2Nlc3N1cyBmaWxzICovCiAgICAgICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOyAgLyogTGUgZmlscyBuJ2EgcGFzIGJlc29pbiBkdSBzb2NrZXQgZCfDqWNvdXRlICovCiAgICAgICAgICAgIHRyYWl0ZXJfY2xpZW50KGNsaWVudF9mZCwgYWRyZXNzZV9jbGllbnQpOwogICAgICAgICAgICAvKiBOZSBqYW1haXMgYXJyaXZlciBpY2kgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBQcm9jZXNzdXMgcMOocmUgKi8KICAgICAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsgICAvKiBMZSBww6hyZSBuJ2EgcGFzIGJlc29pbiBkdSBzb2NrZXQgY2xpZW50ICovCiAgICAgICAgICAgIHByaW50ZigiW1DDqHJlICVkXSBOb3V2ZWF1IGNsaWVudCBjb25uZWN0w6ksIHByb2Nlc3N1cyBmaWxzIGNyw6nDqSA6ICVkXG4iLCAKICAgICAgICAgICAgICAgICAgIGdldHBpZCgpLCBwaWQpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyogOC4gRmVybWV0dXJlIChqYW1haXMgYXR0ZWludCBkYW5zIGNldCBleGVtcGxlKSAqLwogICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICByZXR1cm4gMDsKfTwvcHJlPgo8IS0tIC93cDplbmxpZ2h0ZXIvY29kZWJsb2NrIC0tPgoKPCEtLSB3cDpoZWFkaW5nIHsiYW5jaG9yIjoic2VydmV1ci1odHRwIn0gLS0+CjxoMiBpZD0ic2VydmV1ci1odHRwIiBjbGFzcz0id3AtYmxvY2staGVhZGluZyI+U2VydmV1ciBodHRwIDwvaDI+CjwhLS0gL3dwOmhlYWRpbmcgLS0+Cgo8IS0tIHdwOmVubGlnaHRlci9jb2RlYmxvY2sgeyJsYW5ndWFnZSI6ImMifSAtLT4KPHByZSBjbGFzcz0iRW5saWdodGVySlNSQVciIGRhdGEtZW5saWdodGVyLWxhbmd1YWdlPSJjIiBkYXRhLWVubGlnaHRlci10aGVtZT0iIiBkYXRhLWVubGlnaHRlci1oaWdobGlnaHQ9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW51bWJlcnM9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW9mZnNldD0iIiBkYXRhLWVubGlnaHRlci10aXRsZT0iIiBkYXRhLWVubGlnaHRlci1ncm91cD0iIj4vKiBzZXJ2ZXVyX2h0dHBfbWluaW1hbC5jIC0gVmVyc2lvbiBzaW1wbGlmacOpZSBwb3VyIHRlc3RlciAqLwojaW5jbHVkZSAmbHQ7c3RkaW8uaD4KI2luY2x1ZGUgJmx0O3N0ZGxpYi5oPgojaW5jbHVkZSAmbHQ7c3RyaW5nLmg+CiNpbmNsdWRlICZsdDt1bmlzdGQuaD4KI2luY2x1ZGUgJmx0O3N5cy90eXBlcy5oPgojaW5jbHVkZSAmbHQ7c3lzL3NvY2tldC5oPgojaW5jbHVkZSAmbHQ7bmV0aW5ldC9pbi5oPgojaW5jbHVkZSAmbHQ7YXJwYS9pbmV0Lmg+CgojZGVmaW5lIFBPUlQgODA4MAojZGVmaW5lIEJVRkZFUl9TSVpFIDQwOTYKCmludCBtYWluKHZvaWQpIHsKICAgIGludCBzZXJ2ZXVyX2ZkLCBjbGllbnRfZmQ7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9zZXJ2ZXVyLCBhZHJlc3NlX2NsaWVudDsKICAgIHNvY2tsZW5fdCB0YWlsbGVfY2xpZW50ID0gc2l6ZW9mKGFkcmVzc2VfY2xpZW50KTsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGludCBieXRlc19sdXM7CiAgICBjaGFyICpyZXBvbnNlX29rID0gIkhUVFAvMS4xIDIwMCBPS1xyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQtVHlwZTogdGV4dC9odG1sXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1MZW5ndGg6IDEzNVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbm5lY3Rpb246IGNsb3NlXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiJmx0OyFET0NUWVBFIGh0bWw+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIiZsdDtodG1sPlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7aGVhZD4mbHQ7dGl0bGU+VGVzdCBTZXJ2ZXVyJmx0Oy90aXRsZT4mbHQ7L2hlYWQ+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIiZsdDtib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7aDE+QmllbnZlbnVlIHN1ciBtb24gc2VydmV1ciBIVFRQISZsdDsvaDE+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIiZsdDtwPkNlY2kgZXN0IHVuZSByZXBvbnNlIEhUTUwuJmx0Oy9wPlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7L2JvZHk+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIiZsdDsvaHRtbD5cbiI7CiAgICAKICAgIGNoYXIgKnJlcG9uc2VfNDA0ID0gIkhUVFAvMS4xIDQwNCBOb3QgRm91bmRcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1UeXBlOiB0ZXh0L2h0bWxcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1MZW5ndGg6IDEwNVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uOiBjbG9zZVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICJcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiJmx0OyFET0NUWVBFIGh0bWw+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICImbHQ7aHRtbD5cbiIKICAgICAgICAgICAgICAgICAgICAgICAgIiZsdDtib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiJmx0O2gxPjQwNCAtIFBhZ2Ugbm9uIHRyb3V2ZWUmbHQ7L2gxPlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiJmx0Oy9ib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiJmx0Oy9odG1sPlxuIjsKCiAgICAvKiBDcsOpYXRpb24gc29ja2V0ICovCiAgICBzZXJ2ZXVyX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzZXJ2ZXVyX2ZkICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNyw6lhdGlvbiBzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogQ29uZmlndXJhdGlvbiAqLwogICAgbWVtc2V0KCZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCAwLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2FkZHIuc19hZGRyID0gSU5BRERSX0FOWTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwoKICAgIC8qIEJpbmQgKi8KICAgIGlmIChiaW5kKHNlcnZldXJfZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikmYW1wO2FkcmVzc2Vfc2VydmV1ciwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGJpbmQiKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogTGlzdGVuICovCiAgICBpZiAobGlzdGVuKHNlcnZldXJfZmQsIDUpICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGxpc3RlbiIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KCiAgICBwcmludGYoIlNlcnZldXIgSFRUUCBlbiDDqWNvdXRlIHN1ciBsZSBwb3J0ICVkXG4iLCBQT1JUKTsKCiAgICB3aGlsZSAoMSkgewogICAgICAgIGNsaWVudF9mZCA9IGFjY2VwdChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX2NsaWVudCwgJmFtcDt0YWlsbGVfY2xpZW50KTsKICAgICAgICBpZiAoY2xpZW50X2ZkICZsdDsgMCkgewogICAgICAgICAgICBwZXJyb3IoIkVycmV1ciBhY2NlcHQiKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBwcmludGYoIkNsaWVudCBjb25uZWN0w6kgOiAlczolZFxuIiwgCiAgICAgICAgICAgICAgIGluZXRfbnRvYShhZHJlc3NlX2NsaWVudC5zaW5fYWRkciksIAogICAgICAgICAgICAgICBudG9ocyhhZHJlc3NlX2NsaWVudC5zaW5fcG9ydCkpOwoKICAgICAgICAvKiBMaXJlIGxhIHJlcXXDqnRlIChvcHRpb25uZWwsIG9uIGlnbm9yZSBzb24gY29udGVudSkgKi8KICAgICAgICBieXRlc19sdXMgPSByZWN2KGNsaWVudF9mZCwgYnVmZmVyLCBCVUZGRVJfU0laRSAtIDEsIDApOwogICAgICAgIGlmIChieXRlc19sdXMgPiAwKSB7CiAgICAgICAgICAgIGJ1ZmZlcltieXRlc19sdXNdID0gJ1wwJzsKICAgICAgICAgICAgcHJpbnRmKCJSZXF1w6p0ZSByZcOndWU6XG4lc1xuIiwgYnVmZmVyKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIFLDqXBvbnNlIHNpbXBsZSAqLwogICAgICAgICAgICBpZiAoc3Ryc3RyKGJ1ZmZlciwgIkdFVCAvICIpIHx8IHN0cnN0cihidWZmZXIsICJHRVQgL2luZGV4Lmh0bWwiKSkgewogICAgICAgICAgICAgICAgc2VuZChjbGllbnRfZmQsIHJlcG9uc2Vfb2ssIHN0cmxlbihyZXBvbnNlX29rKSwgMCk7CiAgICAgICAgICAgICAgICBwcmludGYoIlLDqXBvbnNlIDIwMCBPSyBlbnZvecOpZVxuIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZW5kKGNsaWVudF9mZCwgcmVwb25zZV80MDQsIHN0cmxlbihyZXBvbnNlXzQwNCksIDApOwogICAgICAgICAgICAgICAgcHJpbnRmKCJSw6lwb25zZSA0MDQgZW52b3nDqWVcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjbG9zZShjbGllbnRfZmQpOwogICAgICAgIHByaW50ZigiQ29ubmV4aW9uIGZlcm3DqWVcblxuIik7CiAgICB9CgogICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICByZXR1cm4gMDsKfTwvcHJlPgo8IS0tIC93cDplbmxpZ2h0ZXIvY29kZWJsb2NrIC0tPgoKPCEtLSB3cDpoZWFkaW5nIHsiYW5jaG9yIjoic2VydmV1ci1odHRwLW11bHRpLWNsaWVudCJ9IC0tPgo8aDIgaWQ9InNlcnZldXItaHR0cC1tdWx0aS1jbGllbnQiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5TZXJ2ZXVyIGh0dHAgbXVsdGktY2xpZW50PC9oMj4KPCEtLSAvd3A6aGVhZGluZyAtLT4KCjwhLS0gd3A6ZW5saWdodGVyL2NvZGVibG9jayB7Imxhbmd1YWdlIjoiYyJ9IC0tPgo8cHJlIGNsYXNzPSJFbmxpZ2h0ZXJKU1JBVyIgZGF0YS1lbmxpZ2h0ZXItbGFuZ3VhZ2U9ImMiIGRhdGEtZW5saWdodGVyLXRoZW1lPSIiIGRhdGEtZW5saWdodGVyLWhpZ2hsaWdodD0iIiBkYXRhLWVubGlnaHRlci1saW5lbnVtYmVycz0iIiBkYXRhLWVubGlnaHRlci1saW5lb2Zmc2V0PSIiIGRhdGEtZW5saWdodGVyLXRpdGxlPSIiIGRhdGEtZW5saWdodGVyLWdyb3VwPSIiPiNpbmNsdWRlICZsdDtzdGRpby5oPgojaW5jbHVkZSAmbHQ7c3RkbGliLmg+CiNpbmNsdWRlICZsdDtzdHJpbmcuaD4KI2luY2x1ZGUgJmx0O3VuaXN0ZC5oPgojaW5jbHVkZSAmbHQ7c3lzL3R5cGVzLmg+CiNpbmNsdWRlICZsdDtzeXMvc29ja2V0Lmg+CiNpbmNsdWRlICZsdDtzeXMvd2FpdC5oPgojaW5jbHVkZSAmbHQ7bmV0aW5ldC9pbi5oPgojaW5jbHVkZSAmbHQ7YXJwYS9pbmV0Lmg+CiNpbmNsdWRlICZsdDtzaWduYWwuaD4KI2luY2x1ZGUgJmx0O3RpbWUuaD4KCiNkZWZpbmUgUE9SVCA4MDgwCiNkZWZpbmUgQlVGRkVSX1NJWkUgNDA5NgojZGVmaW5lIE1BWF9DTElFTlRTIDEwMAoKaW50IGNsaWVudHNfYWN0aWZzID0gMDsKaW50IGNvbXB0ZXVyX2NsaWVudHMgPSAwOwoKdm9pZCBnZXN0aW9ubmFpcmVfc2lnY2hsZChpbnQgc2lnbm8pIHsKICAgIHdoaWxlICh3YWl0cGlkKC0xLCBOVUxMLCBXTk9IQU5HKSA+IDApIHsKICAgICAgICBjbGllbnRzX2FjdGlmcy0tOwogICAgfQp9CgovKiBFbnZveWVyIHVuZSByw6lwb25zZSBIVFRQICovCnZvaWQgZW52b3llcl9yZXBvbnNlX2h0dHAoaW50IGNsaWVudF9mZCwgY29uc3QgY2hhciAqYm9keSkgewogICAgY2hhciByZXBvbnNlW0JVRkZFUl9TSVpFXTsKICAgIAogICAgc3ByaW50ZihyZXBvbnNlLAogICAgICAgICAgICAiSFRUUC8xLjEgMjAwIE9LXHJcbiIKICAgICAgICAgICAgIkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PVVURi04XHJcbiIKICAgICAgICAgICAgIkNvbnRlbnQtTGVuZ3RoOiAlbGRcclxuIgogICAgICAgICAgICAiQ29ubmVjdGlvbjogY2xvc2VcclxuIgogICAgICAgICAgICAiU2VydmVyOiBBTlNJLUMvMS4wXHJcbiIKICAgICAgICAgICAgIlxyXG4iCiAgICAgICAgICAgICIlcyIsCiAgICAgICAgICAgIHN0cmxlbihib2R5KSwgYm9keSk7CiAgICAKICAgIHNlbmQoY2xpZW50X2ZkLCByZXBvbnNlLCBzdHJsZW4ocmVwb25zZSksIDApOwp9CgovKiBQYWdlIGQnYWNjdWVpbCAqLwp2b2lkIGVudm95ZXJfYWNjdWVpbChpbnQgY2xpZW50X2ZkLCBpbnQgbnVtZXJvX2NsaWVudCkgewogICAgY2hhciBib2R5W0JVRkZFUl9TSVpFXTsKICAgIHRpbWVfdCBub3c7CiAgICBjaGFyIGRhdGVfc3RyWzY0XTsKICAgIAogICAgdGltZSgmYW1wO25vdyk7CiAgICBzdHJmdGltZShkYXRlX3N0ciwgc2l6ZW9mKGRhdGVfc3RyKSwgIiVkLyVtLyVZICVIOiVNOiVTIiwgbG9jYWx0aW1lKCZhbXA7bm93KSk7CiAgICAKICAgIHNwcmludGYoYm9keSwKICAgICAgICAgICAgIiZsdDtodG1sPlxuIgogICAgICAgICAgICAiJmx0O2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7dGl0bGU+U2VydmV1ciBBTlNJIEMmbHQ7L3RpdGxlPlxuIgogICAgICAgICAgICAiJmx0Oy9oZWFkPlxuIgogICAgICAgICAgICAiJmx0O2JvZHk+XG4iCiAgICAgICAgICAgICImbHQ7aDE+U2VydmV1ciBBTlNJIEMmbHQ7L2gxPlxuIgogICAgICAgICAgICAiJmx0O2hyPlxuIgogICAgICAgICAgICAiJmx0O2gyPkNsaWVudCBudW1lcm8gOiAjJWQmbHQ7L2gyPlxuIgogICAgICAgICAgICAiJmx0O3A+Q2xpZW50cyBhY3RpZnMgOiAlZCZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPlRvdGFsIGNsaWVudHMgc2VydmlzIDogJWQmbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7cD5EYXRlL0hldXJlIDogJXMmbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7cD5Qb3J0IDogJWQgfCBQSUQgOiAlZCZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtocj5cbiIKICAgICAgICAgICAgIiZsdDtwPiZsdDthIGhyZWY9Jy9zdGF0cyc+Vm9pciBsZXMgc3RhdGlzdGlxdWVzJmx0Oy9hPiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPiZsdDthIGhyZWY9Jy9xdWl0Jz5RdWl0dGVyJmx0Oy9hPiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDsvYm9keT5cbiIKICAgICAgICAgICAgIiZsdDsvaHRtbD5cbiIsCiAgICAgICAgICAgIG51bWVyb19jbGllbnQsIGNsaWVudHNfYWN0aWZzLCBjb21wdGV1cl9jbGllbnRzLCBkYXRlX3N0ciwgUE9SVCwgZ2V0cGlkKCkpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBQYWdlIHN0YXRpc3RpcXVlcyAqLwp2b2lkIGVudm95ZXJfc3RhdHMoaW50IGNsaWVudF9mZCwgaW50IG51bWVyb19jbGllbnQpIHsKICAgIGNoYXIgYm9keVtCVUZGRVJfU0laRV07CiAgICAKICAgIHNwcmludGYoYm9keSwKICAgICAgICAgICAgIiZsdDtodG1sPlxuIgogICAgICAgICAgICAiJmx0O2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7dGl0bGU+U3RhdGlzdGlxdWVzJmx0Oy90aXRsZT5cbiIKICAgICAgICAgICAgIiZsdDsvaGVhZD5cbiIKICAgICAgICAgICAgIiZsdDtib2R5PlxuIgogICAgICAgICAgICAiJmx0O2gxPlN0YXRpc3RpcXVlcyZsdDsvaDE+XG4iCiAgICAgICAgICAgICImbHQ7aHI+XG4iCiAgICAgICAgICAgICImbHQ7aDI+Vm90cmUgbnVtZXJvIDogIyVkJmx0Oy9oMj5cbiIKICAgICAgICAgICAgIiZsdDtwPkNsaWVudHMgYWN0dWVsbGVtZW50IGNvbm5lY3RlcyA6ICVkJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+VG90YWwgY2xpZW50cyBzZXJ2aXMgZGVwdWlzIGRlbWFycmFnZSA6ICVkJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+Q2FwYWNpdGUgbWF4aW1hbGUgOiAlZCBjbGllbnRzJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O2hyPlxuIgogICAgICAgICAgICAiJmx0O3A+Jmx0O2EgaHJlZj0nLyc+UmV0b3VyIGFjY3VlaWwmbHQ7L2E+Jmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0Oy9ib2R5PlxuIgogICAgICAgICAgICAiJmx0Oy9odG1sPlxuIiwKICAgICAgICAgICAgbnVtZXJvX2NsaWVudCwgY2xpZW50c19hY3RpZnMsIGNvbXB0ZXVyX2NsaWVudHMsIE1BWF9DTElFTlRTKTsKICAgIAogICAgZW52b3llcl9yZXBvbnNlX2h0dHAoY2xpZW50X2ZkLCBib2R5KTsKfQoKLyogUGFnZSA0MDQgKi8Kdm9pZCBlbnZveWVyXzQwNChpbnQgY2xpZW50X2ZkKSB7CiAgICBjaGFyIGJvZHlbQlVGRkVSX1NJWkVdOwogICAgCiAgICBzcHJpbnRmKGJvZHksCiAgICAgICAgICAgICImbHQ7aHRtbD5cbiIKICAgICAgICAgICAgIiZsdDtoZWFkPlxuIgogICAgICAgICAgICAiJmx0O3RpdGxlPjQwNCZsdDsvdGl0bGU+XG4iCiAgICAgICAgICAgICImbHQ7L2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7Ym9keT5cbiIKICAgICAgICAgICAgIiZsdDtoMT40MDQgLSBQYWdlIG5vbiB0cm91dmVlJmx0Oy9oMT5cbiIKICAgICAgICAgICAgIiZsdDtocj5cbiIKICAgICAgICAgICAgIiZsdDtwPkxhIHBhZ2UgZGVtYW5kZWUgbidleGlzdGUgcGFzLiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPiZsdDthIGhyZWY9Jy8nPlJldG91ciBhY2N1ZWlsJmx0Oy9hPiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDsvYm9keT5cbiIKICAgICAgICAgICAgIiZsdDsvaHRtbD5cbiIpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBQYWdlIGF1IHJldm9pciAqLwp2b2lkIGVudm95ZXJfYXVfcmV2b2lyKGludCBjbGllbnRfZmQpIHsKICAgIGNoYXIgYm9keVtCVUZGRVJfU0laRV07CiAgICAKICAgIHNwcmludGYoYm9keSwKICAgICAgICAgICAgIiZsdDtodG1sPlxuIgogICAgICAgICAgICAiJmx0O2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7dGl0bGU+QXUgcmV2b2lyJmx0Oy90aXRsZT5cbiIKICAgICAgICAgICAgIiZsdDsvaGVhZD5cbiIKICAgICAgICAgICAgIiZsdDtib2R5PlxuIgogICAgICAgICAgICAiJmx0O2gxPkF1IHJldm9pciAhJmx0Oy9oMT5cbiIKICAgICAgICAgICAgIiZsdDtocj5cbiIKICAgICAgICAgICAgIiZsdDtwPk1lcmNpIGQnYXZvaXIgdmlzaXRlIG5vdHJlIHNlcnZldXIgQU5TSSBDLiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPiZsdDthIGhyZWY9Jy8nPk5vdXZlbGxlIGNvbm5leGlvbiZsdDsvYT4mbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7L2JvZHk+XG4iCiAgICAgICAgICAgICImbHQ7L2h0bWw+XG4iKTsKICAgIAogICAgZW52b3llcl9yZXBvbnNlX2h0dHAoY2xpZW50X2ZkLCBib2R5KTsKfQoKLyogRXh0cmFpcmUgbGUgY2hlbWluIGRlIGxhIHJlcXXDqnRlIEhUVFAgKi8Kdm9pZCBleHRyYWlyZV9jaGVtaW4oY29uc3QgY2hhciAqcmVxdWV0ZSwgY2hhciAqY2hlbWluKSB7CiAgICBjaGFyIG1ldGhvZFsxNl07CiAgICBjaGFyIHBhdGhbMjU2XTsKICAgIGNoYXIgdmVyc2lvblsxNl07CiAgICAKICAgIHNzY2FuZihyZXF1ZXRlLCAiJXMgJXMgJXMiLCBtZXRob2QsIHBhdGgsIHZlcnNpb24pOwogICAgc3RyY3B5KGNoZW1pbiwgcGF0aCk7Cn0KCnZvaWQgdHJhaXRlcl9jbGllbnQoaW50IGNsaWVudF9mZCwgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2VfY2xpZW50LCBpbnQgbnVtZXJvX2NsaWVudCkgewogICAgY2hhciBidWZmZXJbQlVGRkVSX1NJWkVdOwogICAgaW50IGJ5dGVzX2x1czsKICAgIGNoYXIgY2hlbWluWzI1Nl07CiAgICBjaGFyIGNsaWVudF9pcFtJTkVUX0FERFJTVFJMRU5dOwogICAgCiAgICBpbmV0X250b3AoQUZfSU5FVCwgJmFtcDthZHJlc3NlX2NsaWVudC5zaW5fYWRkciwgY2xpZW50X2lwLCBJTkVUX0FERFJTVFJMRU4pOwogICAgCiAgICBwcmludGYoIltDbGllbnQgIyVkXSBDb25uZWN0ZSBkZXB1aXMgJXM6JWRcbiIsIAogICAgICAgICAgIG51bWVyb19jbGllbnQsIGNsaWVudF9pcCwgbnRvaHMoYWRyZXNzZV9jbGllbnQuc2luX3BvcnQpKTsKICAgIAogICAgLyogTGlyZSBsYSByZXF1w6p0ZSAqLwogICAgYnl0ZXNfbHVzID0gcmVjdihjbGllbnRfZmQsIGJ1ZmZlciwgQlVGRkVSX1NJWkUgLSAxLCAwKTsKICAgIGlmIChieXRlc19sdXMgJmx0Oz0gMCkgewogICAgICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICAgICAgZXhpdCgwKTsKICAgIH0KICAgIAogICAgYnVmZmVyW2J5dGVzX2x1c10gPSAnXDAnOwogICAgZXh0cmFpcmVfY2hlbWluKGJ1ZmZlciwgY2hlbWluKTsKICAgIAogICAgcHJpbnRmKCJbQ2xpZW50ICMlZF0gQ2hlbWluOiAlc1xuIiwgbnVtZXJvX2NsaWVudCwgY2hlbWluKTsKICAgIAogICAgLyogUm91dGVyIHNlbG9uIGxlIGNoZW1pbiAqLwogICAgaWYgKHN0cmNtcChjaGVtaW4sICIvIikgPT0gMCB8fCBzdHJjbXAoY2hlbWluLCAiL2luZGV4Lmh0bWwiKSA9PSAwKSB7CiAgICAgICAgZW52b3llcl9hY2N1ZWlsKGNsaWVudF9mZCwgbnVtZXJvX2NsaWVudCk7CiAgICB9CiAgICBlbHNlIGlmIChzdHJjbXAoY2hlbWluLCAiL3N0YXRzIikgPT0gMCkgewogICAgICAgIGVudm95ZXJfc3RhdHMoY2xpZW50X2ZkLCBudW1lcm9fY2xpZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKHN0cmNtcChjaGVtaW4sICIvcXVpdCIpID09IDApIHsKICAgICAgICBlbnZveWVyX2F1X3Jldm9pcihjbGllbnRfZmQpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZW52b3llcl80MDQoY2xpZW50X2ZkKTsKICAgIH0KICAgIAogICAgcHJpbnRmKCJbQ2xpZW50ICMlZF0gRGVjb25uZXhpb25cbiIsIG51bWVyb19jbGllbnQpOwogICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgIGV4aXQoMCk7Cn0KCmludCBtYWluKHZvaWQpIHsKICAgIGludCBzZXJ2ZXVyX2ZkLCBjbGllbnRfZmQ7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9zZXJ2ZXVyLCBhZHJlc3NlX2NsaWVudDsKICAgIHNvY2tsZW5fdCB0YWlsbGVfY2xpZW50ID0gc2l6ZW9mKGFkcmVzc2VfY2xpZW50KTsKICAgIGludCBvcHQgPSAxOwogICAgaW50IG51bWVyb19ub3V2ZWF1X2NsaWVudDsKICAgIAogICAgLyogR2VzdGlvbiBkZXMgc2lnbmF1eCAqLwogICAgc2lnbmFsKFNJR0NITEQsIGdlc3Rpb25uYWlyZV9zaWdjaGxkKTsKICAgIAogICAgLyogQ3LDqWF0aW9uIHNvY2tldCAqLwogICAgc2VydmV1cl9mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc2VydmV1cl9mZCAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoInNvY2tldCIpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogT3B0aW9uIHJldXNlIGFkZHJlc3MgKi8KICAgIHNldHNvY2tvcHQoc2VydmV1cl9mZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAmYW1wO29wdCwgc2l6ZW9mKG9wdCkpOwogICAgCiAgICAvKiBDb25maWd1cmF0aW9uIGFkcmVzc2UgKi8KICAgIG1lbXNldCgmYW1wO2FkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyLnNfYWRkciA9IElOQUREUl9BTlk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX3BvcnQgPSBodG9ucyhQT1JUKTsKICAgIAogICAgLyogQmluZCAqLwogICAgaWYgKGJpbmQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSkgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJiaW5kIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiBMaXN0ZW4gKi8KICAgIGlmIChsaXN0ZW4oc2VydmV1cl9mZCwgTUFYX0NMSUVOVFMpICZsdDsgMCkgewogICAgICAgIHBlcnJvcigibGlzdGVuIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICBwcmludGYoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoIlNFUlZFVVIgSFRUUCBBTlNJIENcbiIpOwogICAgcHJpbnRmKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKTsKICAgIHByaW50ZigiUG9ydDogJWRcbiIsIFBPUlQpOwogICAgcHJpbnRmKCJVUkw6IGh0dHA6Ly9sb2NhbGhvc3Q6JWQvXG4iLCBQT1JUKTsKICAgIHByaW50ZigiUElEOiAlZFxuIiwgZ2V0cGlkKCkpOwogICAgcHJpbnRmKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiIpOwogICAgCiAgICAvKiBCb3VjbGUgcHJpbmNpcGFsZSAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgICBjbGllbnRfZmQgPSBhY2NlcHQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9jbGllbnQsICZhbXA7dGFpbGxlX2NsaWVudCk7CiAgICAgICAgaWYgKGNsaWVudF9mZCAmbHQ7IDApIHsKICAgICAgICAgICAgcGVycm9yKCJhY2NlcHQiKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGNsaWVudHNfYWN0aWZzKys7CiAgICAgICAgY29tcHRldXJfY2xpZW50cysrOwogICAgICAgIG51bWVyb19ub3V2ZWF1X2NsaWVudCA9IGNvbXB0ZXVyX2NsaWVudHM7CiAgICAgICAgCiAgICAgICAgcHJpbnRmKCJbU0VSVkVVUl0gKysrIENsaWVudCAjJWQgY29ubmVjdGUgKEFjdGlmczogJWQpICsrK1xuIiwgCiAgICAgICAgICAgICAgIG51bWVyb19ub3V2ZWF1X2NsaWVudCwgY2xpZW50c19hY3RpZnMpOwogICAgICAgIAogICAgICAgIHsKICAgICAgICAgICAgcGlkX3QgcGlkID0gZm9yaygpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHBpZCA9PSAwKSB7CiAgICAgICAgICAgICAgICAvKiBQcm9jZXNzdXMgZmlscyAqLwogICAgICAgICAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgICAgICAgICB0cmFpdGVyX2NsaWVudChjbGllbnRfZmQsIGFkcmVzc2VfY2xpZW50LCBudW1lcm9fbm91dmVhdV9jbGllbnQpOwogICAgICAgICAgICAgICAgZXhpdCgwKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChwaWQgPiAwKSB7CiAgICAgICAgICAgICAgICAvKiBQcm9jZXNzdXMgcMOocmUgKi8KICAgICAgICAgICAgICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwZXJyb3IoImZvcmsiKTsKICAgICAgICAgICAgICAgIGNsaWVudHNfYWN0aWZzLS07CiAgICAgICAgICAgICAgICBjbG9zZShjbGllbnRfZmQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgIHJldHVybiAwOwp9PC9wcmU+CjwhLS0gL3dwOmVubGlnaHRlci9jb2RlYmxvY2sgLS0+ZG9jdW1lbnRleGNlcnB0ZG9jdW1lbnRhdXRob3Jkb2N1bWVudGZlYXR1cmVkX21lZGlhZG9jdW1lbnRjb21tZW50X3N0YXR1c2RvY3VtZW50cGluZ19zdGF0dXNkb2N1bWVudHRlbXBsYXRlZG9jdW1lbnRtZXRhX3VhZ19jdXN0b21fcGFnZV9sZXZlbF9jc3Nmb290bm90ZXNkb2N1bWVudGJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzaGVhZGluZ3Nvbmx5SW5jbHVkZUN1cnJlbnRQYWdlb3JkZXJlZFVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRzZXJ2ZXVyX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKQpVQUdIaWRlRGVza3RvcFVBR0hpZGVNb2JVQUdIaWRlVGFiVUFHTG9nZ2VkSW5VQUdMb2dnZWRPdXRVQUdEYXlVQUdSZXNwb25zaXZlQ29uZGl0aW9uc1VBR0FuaW1hdGlvblR5cGVVQUdBbmltYXRpb25UaW1lVUFHQW5pbWF0aW9uRGVsYXlVQUdBbmltYXRpb25FYXNpbmdVQUdBbmltYXRpb25SZXBlYXRVQUdQb3NpdGlvblVBR1N0aWNreUxvY2F0aW9uVUFHU3RpY2t5UmVzdHJpY3RlZFVBR1N0aWNreU9mZnNldGlubmVyQmxvY2tzY2xpZW50SWRpc1ZhbGlkb3JpZ2luYWxDb250ZW50bmFtZWF0dHJpYnV0ZXNvcmRlcmVkdmFsdWVzVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudEFGX0lORVQgOiBGYW1pbGxlIGQnYWRyZXNzZXMgSVB2NFVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRTT0NLX1NUUkVBTSA6IFR5cGUgZGUgc29ja2V0IChUQ1AsIGZpYWJsZSwgY29ubmV4aW9uIG9yaWVudMOpZSBmbHV4KVVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnQwIDogUHJvdG9jb2xlIHBhciBkw6lmYXV0IChUQ1AgcG91ciBTT0NLX1NUUkVBTSlVQUdIaWRlRGVza3RvcFVBR0hpZGVNb2JVQUdIaWRlVGFiVUFHTG9nZ2VkSW5VQUdMb2dnZWRPdXRVQUdEYXlVQUdSZXNwb25zaXZlQ29uZGl0aW9uc1VBR0FuaW1hdGlvblR5cGVVQUdBbmltYXRpb25UaW1lVUFHQW5pbWF0aW9uRGVsYXlVQUdBbmltYXRpb25FYXNpbmdVQUdBbmltYXRpb25SZXBlYXRVQUdQb3NpdGlvblVBR1N0aWNreUxvY2F0aW9uVUFHU3RpY2t5UmVzdHJpY3RlZFVBR1N0aWNreU9mZnNldGlubmVyQmxvY2tzY2xpZW50SWRpc1ZhbGlkb3JpZ2luYWxDb250ZW50bmFtZWF0dHJpYnV0ZXNjb250ZW50UmV0b3VyIDogRGVzY3JpcHRldXIgZGUgZmljaGllciAoZW50aWVyKSBvdSAtMSBzaSBlcnJldXJVQUdIaWRlRGVza3RvcFVBR0hpZGVNb2JVQUdIaWRlVGFiVUFHTG9nZ2VkSW5VQUdMb2dnZWRPdXRVQUdEYXlVQUdSZXNwb25zaXZlQ29uZGl0aW9uc1VBR0FuaW1hdGlvblR5cGVVQUdBbmltYXRpb25UaW1lVUFHQW5pbWF0aW9uRGVsYXlVQUdBbmltYXRpb25FYXNpbmdVQUdBbmltYXRpb25SZXBlYXRVQUdQb3NpdGlvblVBR1N0aWNreUxvY2F0aW9uVUFHU3RpY2t5UmVzdHJpY3RlZFVBR1N0aWNreU9mZnNldGlubmVyQmxvY2tzY2xpZW50SWRpc1ZhbGlkb3JpZ2luYWxDb250ZW50bmFtZWF0dHJpYnV0ZXNjb250ZW50U2VydmV1ciBUQ1BsZXZlbGFuY2hvclVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRsYW5ndWFnZXRoZW1laGlnaGxpZ2h0bGluZW51bWJlcnNsaW5lb2Zmc2V0dGl0bGVncm91cFVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRNYWtlZmlsZWxldmVsYW5jaG9yVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudGxhbmd1YWdldGhlbWVoaWdobGlnaHRsaW5lbnVtYmVyc2xpbmVvZmZzZXR0aXRsZWdyb3VwVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudENsaWVudCBUQ1BsZXZlbGFuY2hvclVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRsYW5ndWFnZXRoZW1laGlnaGxpZ2h0bGluZW51bWJlcnNsaW5lb2Zmc2V0dGl0bGVncm91cFVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRNYWtlZmlsZWxldmVsYW5jaG9yVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudGxhbmd1YWdldGhlbWVoaWdobGlnaHRsaW5lbnVtYmVyc2xpbmVvZmZzZXR0aXRsZWdyb3VwVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudE11dGlfc2VydmV1ciAoZm9yaylsZXZlbGFuY2hvclVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRsYW5ndWFnZXRoZW1laGlnaGxpZ2h0bGluZW51bWJlcnNsaW5lb2Zmc2V0dGl0bGVncm91cFVBR0hpZGVEZXNrdG9wVUFHSGlkZU1vYlVBR0hpZGVUYWJVQUdMb2dnZWRJblVBR0xvZ2dlZE91dFVBR0RheVVBR1Jlc3BvbnNpdmVDb25kaXRpb25zVUFHQW5pbWF0aW9uVHlwZVVBR0FuaW1hdGlvblRpbWVVQUdBbmltYXRpb25EZWxheVVBR0FuaW1hdGlvbkVhc2luZ1VBR0FuaW1hdGlvblJlcGVhdFVBR1Bvc2l0aW9uVUFHU3RpY2t5TG9jYXRpb25VQUdTdGlja3lSZXN0cmljdGVkVUFHU3RpY2t5T2Zmc2V0aW5uZXJCbG9ja3NjbGllbnRJZGlzVmFsaWRvcmlnaW5hbENvbnRlbnRuYW1lYXR0cmlidXRlc2NvbnRlbnRTZXJ2ZXVyIGh0dHAgbGV2ZWxhbmNob3JVQUdIaWRlRGVza3RvcFVBR0hpZGVNb2JVQUdIaWRlVGFiVUFHTG9nZ2VkSW5VQUdMb2dnZWRPdXRVQUdEYXlVQUdSZXNwb25zaXZlQ29uZGl0aW9uc1VBR0FuaW1hdGlvblR5cGVVQUdBbmltYXRpb25UaW1lVUFHQW5pbWF0aW9uRGVsYXlVQUdBbmltYXRpb25FYXNpbmdVQUdBbmltYXRpb25SZXBlYXRVQUdQb3NpdGlvblVBR1N0aWNreUxvY2F0aW9uVUFHU3RpY2t5UmVzdHJpY3RlZFVBR1N0aWNreU9mZnNldGlubmVyQmxvY2tzY2xpZW50SWRpc1ZhbGlkb3JpZ2luYWxDb250ZW50bmFtZWF0dHJpYnV0ZXNjb250ZW50bGFuZ3VhZ2V0aGVtZWhpZ2hsaWdodGxpbmVudW1iZXJzbGluZW9mZnNldHRpdGxlZ3JvdXBVQUdIaWRlRGVza3RvcFVBR0hpZGVNb2JVQUdIaWRlVGFiVUFHTG9nZ2VkSW5VQUdMb2dnZWRPdXRVQUdEYXlVQUdSZXNwb25zaXZlQ29uZGl0aW9uc1VBR0FuaW1hdGlvblR5cGVVQUdBbmltYXRpb25UaW1lVUFHQW5pbWF0aW9uRGVsYXlVQUdBbmltYXRpb25FYXNpbmdVQUdBbmltYXRpb25SZXBlYXRVQUdQb3NpdGlvblVBR1N0aWNreUxvY2F0aW9uVUFHU3RpY2t5UmVzdHJpY3RlZFVBR1N0aWNreU9mZnNldGlubmVyQmxvY2tzY2xpZW50SWRpc1ZhbGlkb3JpZ2luYWxDb250ZW50bmFtZWF0dHJpYnV0ZXNjb250ZW50U2VydmV1ciBodHRwIG11bHRpLWNsaWVudGxldmVsYW5jaG9yVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc2NsaWVudElkaXNWYWxpZG9yaWdpbmFsQ29udGVudG5hbWVhdHRyaWJ1dGVzY29udGVudGxhbmd1YWdldGhlbWVoaWdobGlnaHRsaW5lbnVtYmVyc2xpbmVvZmZzZXR0aXRsZWdyb3VwVUFHSGlkZURlc2t0b3BVQUdIaWRlTW9iVUFHSGlkZVRhYlVBR0xvZ2dlZEluVUFHTG9nZ2VkT3V0VUFHRGF5VUFHUmVzcG9uc2l2ZUNvbmRpdGlvbnNVQUdBbmltYXRpb25UeXBlVUFHQW5pbWF0aW9uVGltZVVBR0FuaW1hdGlvbkRlbGF5VUFHQW5pbWF0aW9uRWFzaW5nVUFHQW5pbWF0aW9uUmVwZWF0VUFHUG9zaXRpb25VQUdTdGlja3lMb2NhdGlvblVBR1N0aWNreVJlc3RyaWN0ZWRVQUdTdGlja3lPZmZzZXRpbm5lckJsb2Nrc3N0YXRlc2F2ZWRBdHN0YXRlc2F2ZWRCeSBUQ1AFBwgECAQIBggFBkEACQgHmrIDCAcIBggOCA4IC0gBBBoJCAYIBw8ECggWBw5KAAsMBhdQABFSAAsREw8LCAcPBAoHLQ5KAAsMBhdQABFSAAsREw8LCAcPBAoHBg5KAAsMBhdQABFSAAsREw8LCAcPBAoHIQ5KAAsMBhdQABFSAAsREw8LCAcPBAoHgwEOSgALDAYXUAARUgALERMPCwgHDwQKBy8OSgALDAYXUAARUgALERMPCwgHDwQKBzgOSgALDAYXUAARUgALERMPCwgHDwQKBwsFBg5KAAsMBhdQABFSAAsREw8LCAcPBAoHCAUJCwpFAA5KAAsMBhdQABFSAAsREw8LCAcPBAoHCAUGDkoACwwGF1AAEVIACxETDwsIBw8ECgcIBQkLCkUADkoACwwGF1AAEVIACxETDwsIBw8ECgcKBQYOSgALDAYXUAARUgALERMPCwgHDwQKBwgFCQsKRQAOSgALDAYXUAARUgALERMPCwgHDwQKBwgFBg5KAAsMBhdQABFSAAsREw8LCAcPBAoHCAUJCwpFAA5KAAsMBhdQABFSAAsREw8LCAcPBAoHEwUGDkoACwwGF1AAEVIACxETDwsIBw8ECgcIBQkLCkUADkoACwwGF1AAEVIACxETDwsIBw8ECgcNBQYOSgALDAYXUAARUgALERMPCwgHDwQKBwgFCQsKRQAOSgALDAYXUAARUgALERMPCwgHDwQKBxkFBg5KAAsMBhdQABFSAAsREw8LCAcPBAoHCAUJCwpFAA5KAAsMBhdQABFSAAsREw8LBQcFBwEDEgEEAAABAAAAAQYAAQEAALIEAU9CAQEAQQAAQQACAEEAAEEAAgBBAAIAQQACAEEAAgBBAAIAQQAAQQACAEEAAEEAAgBBAABBAAIAQQAAQQACAEEAAEEAAgBBAABBAAIAQQAAA0H6AwHfBAB9AXcTMjAyNi0wNC0wM1QwNzo0OTozMncRc29ja2V0cy1lbi1jLWFuc2l3B3B1Ymxpc2h9AX0AdwZjbG9zZWR3BmNsb3NlZHcAdwB3AHckYjYxM2IxYjAtNTc3YS00ZmNmLTliMzQtYzE1M2NiYWEyMzFmeHeNCDxuYXYgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzIj48b2w+PGxpPjxhIGNsYXNzPSJ3cC1ibG9jay10YWJsZS1vZi1jb250ZW50c19fZW50cnkiIGhyZWY9Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI3NlcnZldXItdGNwIj5TZXJ2ZXVyIFRDUDwvYT48b2w+PGxpPjxhIGNsYXNzPSJ3cC1ibG9jay10YWJsZS1vZi1jb250ZW50c19fZW50cnkiIGhyZWY9Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI21ha2VmaWxlIj5NYWtlZmlsZTwvYT48L2xpPjwvb2w+PC9saT48bGk+PGEgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzX19lbnRyeSIgaHJlZj0iaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jY2xpZW50LXRjcCI+Q2xpZW50IFRDUDwvYT48b2w+PGxpPjxhIGNsYXNzPSJ3cC1ibG9jay10YWJsZS1vZi1jb250ZW50c19fZW50cnkiIGhyZWY9Imh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI21ha2VmaWxlLTEiPk1ha2VmaWxlPC9hPjwvbGk+PC9vbD48L2xpPjxsaT48YSBjbGFzcz0id3AtYmxvY2stdGFibGUtb2YtY29udGVudHNfX2VudHJ5IiBocmVmPSJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNtdXRpLXNlcnZldXItZm9yayI+TXV0aV9zZXJ2ZXVyIChmb3JrKTwvYT48L2xpPjxsaT48YSBjbGFzcz0id3AtYmxvY2stdGFibGUtb2YtY29udGVudHNfX2VudHJ5IiBocmVmPSJodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNzZXJ2ZXVyLWh0dHAiPlNlcnZldXIgaHR0cCA8L2E+PC9saT48bGk+PGEgY2xhc3M9IndwLWJsb2NrLXRhYmxlLW9mLWNvbnRlbnRzX19lbnRyeSIgaHJlZj0iaHR0cHM6Ly93b3JrYm9vdC5mci9jaWVsYS9zb2NrZXRzLWVuLWMtYW5zaS8jc2VydmV1ci1odHRwLW11bHRpLWNsaWVudCI+U2VydmV1ciBodHRwIG11bHRpLWNsaWVudDwvYT48L2xpPjwvb2w+PC9uYXY+dxZjb3JlL3RhYmxlLW9mLWNvbnRlbnRzdQd2Awdjb250ZW50dwtTZXJ2ZXVyIFRDUAVsZXZlbH0CBGxpbmt3OGh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI3NlcnZldXItdGNwdgMHY29udGVudHcITWFrZWZpbGUFbGV2ZWx9AwRsaW5rdzVodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNtYWtlZmlsZXYDB2NvbnRlbnR3CkNsaWVudCBUQ1AFbGV2ZWx9AgRsaW5rdzdodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNjbGllbnQtdGNwdgMHY29udGVudHcITWFrZWZpbGUFbGV2ZWx9AwRsaW5rdzdodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNtYWtlZmlsZS0xdgMHY29udGVudHcTTXV0aV9zZXJ2ZXVyIChmb3JrKQVsZXZlbH0CBGxpbmt3Pmh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI211dGktc2VydmV1ci1mb3JrdgMHY29udGVudHcNU2VydmV1ciBodHRwIAVsZXZlbH0CBGxpbmt3OWh0dHBzOi8vd29ya2Jvb3QuZnIvY2llbGEvc29ja2V0cy1lbi1jLWFuc2kvI3NlcnZldXItaHR0cHYDB2NvbnRlbnR3GVNlcnZldXIgaHR0cCBtdWx0aS1jbGllbnQFbGV2ZWx9AgRsaW5rd0ZodHRwczovL3dvcmtib290LmZyL2NpZWxhL3NvY2tldHMtZW4tYy1hbnNpLyNzZXJ2ZXVyLWh0dHAtbXVsdGktY2xpZW50eXh5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHckZDA2MzdlNWYtOWE1Yi00YWRjLWE1NjctNmYyNGQ3N2JiMGFkeHdbPHByZSBjbGFzcz0id3AtYmxvY2stY29kZSI+PGNvZGU+c2VydmV1cl9mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCkKPC9jb2RlPjwvcHJlPncJY29yZS9jb2RleXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JGI5NmMzMDg0LWVlZDgtNDRlNC05ZTFhLWUzNjk1YWYzM2U2N3h3JTx1bCBjbGFzcz0id3AtYmxvY2stbGlzdCI+CgoKCgoKPC91bD53CWNvcmUvbGlzdHl3AHl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQ2Zjg3OWQ0MC02NGRiLTRlZDAtOTU5Zi1iMTRiNzI0NmI0MGV4dyo8bGk+QUZfSU5FVCA6IEZhbWlsbGUgZCdhZHJlc3NlcyBJUHY0PC9saT53DmNvcmUvbGlzdC1pdGVteXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JDc4ZWEwNzIxLTNhMTYtNDkwMC1iNzNlLTI5NGNjYTg3ZTQ4OHh3TTxsaT5TT0NLX1NUUkVBTSA6IFR5cGUgZGUgc29ja2V0IChUQ1AsIGZpYWJsZSwgY29ubmV4aW9uIG9yaWVudMOpZSBmbHV4KTwvbGk+dw5jb3JlL2xpc3QtaXRlbXl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQ5MDY0OTcyMi04OGZkLTQ4YzctOWUyOC0zZjg3Y2M3MzA3MWF4dzk8bGk+MCA6IFByb3RvY29sZSBwYXIgZMOpZmF1dCAoVENQIHBvdXIgU09DS19TVFJFQU0pPC9saT53DmNvcmUvbGlzdC1pdGVteXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JDNjMzhkODRlLTYwZGQtNGYwMi1iODYxLTdmNWRiNzRlYTNjYXh3QTxsaT5SZXRvdXIgOiBEZXNjcmlwdGV1ciBkZSBmaWNoaWVyIChlbnRpZXIpIG91IC0xIHNpIGVycmV1cjwvbGk+dw5jb3JlL2xpc3QtaXRlbXl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQwYzVmY2Q1NS0yYTFjLTQwMDctYmI4OS1lNmI0ZmM4OWNmMzJ4dz48aDIgaWQ9InNlcnZldXItdGNwIiBjbGFzcz0id3AtYmxvY2staGVhZGluZyI+U2VydmV1ciBUQ1A8L2gyPncMY29yZS9oZWFkaW5nfQJ3C3NlcnZldXItdGNweXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JGZkNDVkYzM4LTJjMWMtNDQ0Yi05NjM5LTdhOTMwMjM3OTRiZHh3nBY8cHJlIGNsYXNzPSJFbmxpZ2h0ZXJKU1JBVyIgZGF0YS1lbmxpZ2h0ZXItbGFuZ3VhZ2U9ImMiIGRhdGEtZW5saWdodGVyLXRoZW1lPSIiIGRhdGEtZW5saWdodGVyLWhpZ2hsaWdodD0iIiBkYXRhLWVubGlnaHRlci1saW5lbnVtYmVycz0iIiBkYXRhLWVubGlnaHRlci1saW5lb2Zmc2V0PSIiIGRhdGEtZW5saWdodGVyLXRpdGxlPSIiIGRhdGEtZW5saWdodGVyLWdyb3VwPSIiPiNpbmNsdWRlICZsdDtzdGRpby5oPgojaW5jbHVkZSAmbHQ7c3RkbGliLmg+CiNpbmNsdWRlICZsdDtzdHJpbmcuaD4KI2luY2x1ZGUgJmx0O3VuaXN0ZC5oPgojaW5jbHVkZSAmbHQ7c3lzL3R5cGVzLmg+CiNpbmNsdWRlICZsdDtzeXMvc29ja2V0Lmg+CiNpbmNsdWRlICZsdDtuZXRpbmV0L2luLmg+CiNpbmNsdWRlICZsdDthcnBhL2luZXQuaD4KI2luY2x1ZGUgJmx0O25ldGRiLmg+CgojZGVmaW5lIFBPUlQgODg4OAojZGVmaW5lIEJVRkZFUl9TSVpFIDEwMjQKCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsKICAgIGludCBzb2NrX2ZkOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2Vfc2VydmV1cjsKICAgIHN0cnVjdCBob3N0ZW50ICpzZXJ2ZXVyOwogICAgY2hhciBidWZmZXJbQlVGRkVSX1NJWkVdOwogICAgY2hhciBtZXNzYWdlW0JVRkZFUl9TSVpFXTsKICAgIGludCBieXRlc19yZWN1czsKICAgIHN0cnVjdCBpbl9hZGRyICoqYWRkcl9saXN0OyAgLyogUG91ciB1bmUgdmVyc2lvbiBwbHVzIGV4cGxpY2l0ZSAqLwoKICAgIC8qIFbDqXJpZmljYXRpb24gZGVzIGFyZ3VtZW50cyAqLwogICAgaWYgKGFyZ2MgJmx0OyAyKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJVc2FnZTogJXMgJmx0O2FkcmVzc2Vfc2VydmV1cj5cbiIsIGFyZ3ZbMF0pOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KCiAgICAvKiAxLiBDcsOpYXRpb24gZHUgc29ja2V0ICovCiAgICBzb2NrX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzb2NrX2ZkICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNyw6lhdGlvbiBzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMi4gUsOpc29sdXRpb24gZHUgbm9tIGQnaMO0dGUgKi8KICAgIHNlcnZldXIgPSBnZXRob3N0YnluYW1lKGFyZ3ZbMV0pOwogICAgaWYgKHNlcnZldXIgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiSMO0dGUgaW5jb25udSA6ICVzXG4iLCBhcmd2WzFdKTsKICAgICAgICBjbG9zZShzb2NrX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMy4gQ29uZmlndXJhdGlvbiBkZSBsJ2FkcmVzc2UgKi8KICAgIG1lbXNldCgmYW1wO2FkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgCiAgICAvKiBNw6l0aG9kZSBhbHRlcm5hdGl2ZSBwbHVzIGV4cGxpY2l0ZSAqLwogICAgYWRkcl9saXN0ID0gKHN0cnVjdCBpbl9hZGRyICoqKXNlcnZldXItPmhfYWRkcl9saXN0OwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyID0gKmFkZHJfbGlzdFswXTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwoKICAgIC8qIDQuIENvbm5leGlvbiBhdSBzZXJ2ZXVyICovCiAgICBpZiAoY29ubmVjdChzb2NrX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjb25uZWN0Iik7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIHByaW50ZigiQ29ubmVjdMOpIGF1IHNlcnZldXIgJXM6JWRcbiIsIGFyZ3ZbMV0sIFBPUlQpOwogICAgcHJpbnRmKCJBZHJlc3NlIElQIDogJXNcbiIsIGluZXRfbnRvYShhZHJlc3NlX3NlcnZldXIuc2luX2FkZHIpKTsKCiAgICAvKiA1LiDDiWNoYW5nZSBkZSBkb25uw6llcyAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgICBwcmludGYoIk1lc3NhZ2Ugw6AgZW52b3llciAob3UgJ3F1aXQnIHBvdXIgcXVpdHRlcikgOiAiKTsKICAgICAgICBmZ2V0cyhtZXNzYWdlLCBCVUZGRVJfU0laRSwgc3RkaW4pOwogICAgICAgIAogICAgICAgIC8qIFN1cHByZXNzaW9uIGR1IHNhdXQgZGUgbGlnbmUgKi8KICAgICAgICBtZXNzYWdlW3N0cmNzcG4obWVzc2FnZSwgIlxuIildID0gJ1wwJzsKICAgICAgICAKICAgICAgICBpZiAoc3RyY21wKG1lc3NhZ2UsICJxdWl0IikgPT0gMCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogRW52b2kgKi8KICAgICAgICBzZW5kKHNvY2tfZmQsIG1lc3NhZ2UsIHN0cmxlbihtZXNzYWdlKSwgMCk7CiAgICAgICAgCiAgICAgICAgLyogUsOpY2VwdGlvbiBkZSBsYSByw6lwb25zZSAqLwogICAgICAgIGJ5dGVzX3JlY3VzID0gcmVjdihzb2NrX2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCk7CiAgICAgICAgaWYgKGJ5dGVzX3JlY3VzICZsdDs9IDApIHsKICAgICAgICAgICAgcHJpbnRmKCJTZXJ2ZXVyIGTDqWNvbm5lY3TDqVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBidWZmZXJbYnl0ZXNfcmVjdXNdID0gJ1wwJzsKICAgICAgICBwcmludGYoIlLDqXBvbnNlIGR1IHNlcnZldXIgOiAlc1xuIiwgYnVmZmVyKTsKICAgIH0KCiAgICAvKiA2LiBGZXJtZXR1cmUgKi8KICAgIGNsb3NlKHNvY2tfZmQpOwogICAgcmV0dXJuIDA7Cn08L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3jRQjaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CiNpbmNsdWRlIDxuZXRkYi5oPgoKI2RlZmluZSBQT1JUIDg4ODgKI2RlZmluZSBCVUZGRVJfU0laRSAxMDI0CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CiAgICBpbnQgc29ja19mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXI7CiAgICBzdHJ1Y3QgaG9zdGVudCAqc2VydmV1cjsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGNoYXIgbWVzc2FnZVtCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfcmVjdXM7CiAgICBzdHJ1Y3QgaW5fYWRkciAqKmFkZHJfbGlzdDsgIC8qIFBvdXIgdW5lIHZlcnNpb24gcGx1cyBleHBsaWNpdGUgKi8KCiAgICAvKiBWw6lyaWZpY2F0aW9uIGRlcyBhcmd1bWVudHMgKi8KICAgIGlmIChhcmdjIDwgMikgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6ICVzIDxhZHJlc3NlX3NlcnZldXI+XG4iLCBhcmd2WzBdKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMS4gQ3LDqWF0aW9uIGR1IHNvY2tldCAqLwogICAgc29ja19mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc29ja19mZCA8IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjcsOpYXRpb24gc29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDIuIFLDqXNvbHV0aW9uIGR1IG5vbSBkJ2jDtHRlICovCiAgICBzZXJ2ZXVyID0gZ2V0aG9zdGJ5bmFtZShhcmd2WzFdKTsKICAgIGlmIChzZXJ2ZXVyID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkjDtHRlIGluY29ubnUgOiAlc1xuIiwgYXJndlsxXSk7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDMuIENvbmZpZ3VyYXRpb24gZGUgbCdhZHJlc3NlICovCiAgICBtZW1zZXQoJmFkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgCiAgICAvKiBNw6l0aG9kZSBhbHRlcm5hdGl2ZSBwbHVzIGV4cGxpY2l0ZSAqLwogICAgYWRkcl9saXN0ID0gKHN0cnVjdCBpbl9hZGRyICoqKXNlcnZldXItPmhfYWRkcl9saXN0OwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyID0gKmFkZHJfbGlzdFswXTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwoKICAgIC8qIDQuIENvbm5leGlvbiBhdSBzZXJ2ZXVyICovCiAgICBpZiAoY29ubmVjdChzb2NrX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFkcmVzc2Vfc2VydmV1ciwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpIDwgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNvbm5lY3QiKTsKICAgICAgICBjbG9zZShzb2NrX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgcHJpbnRmKCJDb25uZWN0w6kgYXUgc2VydmV1ciAlczolZFxuIiwgYXJndlsxXSwgUE9SVCk7CiAgICBwcmludGYoIkFkcmVzc2UgSVAgOiAlc1xuIiwgaW5ldF9udG9hKGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkcikpOwoKICAgIC8qIDUuIMOJY2hhbmdlIGRlIGRvbm7DqWVzICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIHByaW50ZigiTWVzc2FnZSDDoCBlbnZveWVyIChvdSAncXVpdCcgcG91ciBxdWl0dGVyKSA6ICIpOwogICAgICAgIGZnZXRzKG1lc3NhZ2UsIEJVRkZFUl9TSVpFLCBzdGRpbik7CiAgICAgICAgCiAgICAgICAgLyogU3VwcHJlc3Npb24gZHUgc2F1dCBkZSBsaWduZSAqLwogICAgICAgIG1lc3NhZ2Vbc3RyY3NwbihtZXNzYWdlLCAiXG4iKV0gPSAnXDAnOwogICAgICAgIAogICAgICAgIGlmIChzdHJjbXAobWVzc2FnZSwgInF1aXQiKSA9PSAwKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKiBFbnZvaSAqLwogICAgICAgIHNlbmQoc29ja19mZCwgbWVzc2FnZSwgc3RybGVuKG1lc3NhZ2UpLCAwKTsKICAgICAgICAKICAgICAgICAvKiBSw6ljZXB0aW9uIGRlIGxhIHLDqXBvbnNlICovCiAgICAgICAgYnl0ZXNfcmVjdXMgPSByZWN2KHNvY2tfZmQsIGJ1ZmZlciwgQlVGRkVSX1NJWkUgLSAxLCAwKTsKICAgICAgICBpZiAoYnl0ZXNfcmVjdXMgPD0gMCkgewogICAgICAgICAgICBwcmludGYoIlNlcnZldXIgZMOpY29ubmVjdMOpXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJ1ZmZlcltieXRlc19yZWN1c10gPSAnXDAnOwogICAgICAgIHByaW50ZigiUsOpcG9uc2UgZHUgc2VydmV1ciA6ICVzXG4iLCBidWZmZXIpOwogICAgfQoKICAgIC8qIDYuIEZlcm1ldHVyZSAqLwogICAgY2xvc2Uoc29ja19mZCk7CiAgICByZXR1cm4gMDsKfXcBY3cAdwB3AHcAdwB3AHl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQ1ZThiYTA2Ni0wZmU5LTRiNGQtYjJiMi1lZGYyZWRkMmRiNzd4dzg8aDMgaWQ9Im1ha2VmaWxlIiBjbGFzcz0id3AtYmxvY2staGVhZGluZyI+TWFrZWZpbGU8L2gzPncMY29yZS9oZWFkaW5nfQN3CG1ha2VmaWxleXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JGM1YTg3ZWM0LTFmMDMtNDNhMy05ZjAxLWY2Mzk1ZjViNjI3ZHh3iAM8cHJlIGNsYXNzPSJFbmxpZ2h0ZXJKU1JBVyIgZGF0YS1lbmxpZ2h0ZXItbGFuZ3VhZ2U9Im1kIiBkYXRhLWVubGlnaHRlci10aGVtZT0iIiBkYXRhLWVubGlnaHRlci1oaWdobGlnaHQ9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW51bWJlcnM9IiIgZGF0YS1lbmxpZ2h0ZXItbGluZW9mZnNldD0iIiBkYXRhLWVubGlnaHRlci10aXRsZT0iIiBkYXRhLWVubGlnaHRlci1ncm91cD0iIj5DQyA9IGdjYwpDRkxBR1MgPSAtV2FsbCAtV2V4dHJhIC1hbnNpIC1wZWRhbnRpYwoKYWxsOiBzZXJ2ZXVyCgpzZXJ2ZXVyOiBzZXJ2ZXVyX3RjcC5jCgkkKENDKSAkKENGTEFHUykgLW8gc2VydmV1ciBzZXJ2ZXVyX3RjcC5jCgpjbGVhbjoKCXJtIC1mIHNlcnZldXIKCi5QSE9OWTogYWxsIGNsZWFuCjwvcHJlPncTZW5saWdodGVyL2NvZGVibG9ja3eqAUNDID0gZ2NjCkNGTEFHUyA9IC1XYWxsIC1XZXh0cmEgLWFuc2kgLXBlZGFudGljCgphbGw6IHNlcnZldXIKCnNlcnZldXI6IHNlcnZldXJfdGNwLmMKCSQoQ0MpICQoQ0ZMQUdTKSAtbyBzZXJ2ZXVyIHNlcnZldXJfdGNwLmMKCmNsZWFuOgoJcm0gLWYgc2VydmV1cgoKLlBIT05ZOiBhbGwgY2xlYW4KdwJtZHcAdwB3AHcAdwB3AHl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQ1MGU1MTMwNC05MDg4LTQ2ZjEtYWU0NC02MDhkMjdhMjUxNjN4dzw8aDIgaWQ9ImNsaWVudC10Y3AiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5DbGllbnQgVENQPC9oMj53DGNvcmUvaGVhZGluZ30CdwpjbGllbnQtdGNweXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JDkwMTk5YmUzLTdjMGItNDVlNC04OGI4LTQ0YTI0ZDFiYWI1N3h3nBY8cHJlIGNsYXNzPSJFbmxpZ2h0ZXJKU1JBVyIgZGF0YS1lbmxpZ2h0ZXItbGFuZ3VhZ2U9ImMiIGRhdGEtZW5saWdodGVyLXRoZW1lPSIiIGRhdGEtZW5saWdodGVyLWhpZ2hsaWdodD0iIiBkYXRhLWVubGlnaHRlci1saW5lbnVtYmVycz0iIiBkYXRhLWVubGlnaHRlci1saW5lb2Zmc2V0PSIiIGRhdGEtZW5saWdodGVyLXRpdGxlPSIiIGRhdGEtZW5saWdodGVyLWdyb3VwPSIiPiNpbmNsdWRlICZsdDtzdGRpby5oPgojaW5jbHVkZSAmbHQ7c3RkbGliLmg+CiNpbmNsdWRlICZsdDtzdHJpbmcuaD4KI2luY2x1ZGUgJmx0O3VuaXN0ZC5oPgojaW5jbHVkZSAmbHQ7c3lzL3R5cGVzLmg+CiNpbmNsdWRlICZsdDtzeXMvc29ja2V0Lmg+CiNpbmNsdWRlICZsdDtuZXRpbmV0L2luLmg+CiNpbmNsdWRlICZsdDthcnBhL2luZXQuaD4KI2luY2x1ZGUgJmx0O25ldGRiLmg+CgojZGVmaW5lIFBPUlQgODg4OAojZGVmaW5lIEJVRkZFUl9TSVpFIDEwMjQKCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsKICAgIGludCBzb2NrX2ZkOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2Vfc2VydmV1cjsKICAgIHN0cnVjdCBob3N0ZW50ICpzZXJ2ZXVyOwogICAgY2hhciBidWZmZXJbQlVGRkVSX1NJWkVdOwogICAgY2hhciBtZXNzYWdlW0JVRkZFUl9TSVpFXTsKICAgIGludCBieXRlc19yZWN1czsKICAgIHN0cnVjdCBpbl9hZGRyICoqYWRkcl9saXN0OyAgLyogUG91ciB1bmUgdmVyc2lvbiBwbHVzIGV4cGxpY2l0ZSAqLwoKICAgIC8qIFbDqXJpZmljYXRpb24gZGVzIGFyZ3VtZW50cyAqLwogICAgaWYgKGFyZ2MgJmx0OyAyKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJVc2FnZTogJXMgJmx0O2FkcmVzc2Vfc2VydmV1cj5cbiIsIGFyZ3ZbMF0pOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KCiAgICAvKiAxLiBDcsOpYXRpb24gZHUgc29ja2V0ICovCiAgICBzb2NrX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzb2NrX2ZkICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNyw6lhdGlvbiBzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMi4gUsOpc29sdXRpb24gZHUgbm9tIGQnaMO0dGUgKi8KICAgIHNlcnZldXIgPSBnZXRob3N0YnluYW1lKGFyZ3ZbMV0pOwogICAgaWYgKHNlcnZldXIgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiSMO0dGUgaW5jb25udSA6ICVzXG4iLCBhcmd2WzFdKTsKICAgICAgICBjbG9zZShzb2NrX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMy4gQ29uZmlndXJhdGlvbiBkZSBsJ2FkcmVzc2UgKi8KICAgIG1lbXNldCgmYW1wO2FkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgCiAgICAvKiBNw6l0aG9kZSBhbHRlcm5hdGl2ZSBwbHVzIGV4cGxpY2l0ZSAqLwogICAgYWRkcl9saXN0ID0gKHN0cnVjdCBpbl9hZGRyICoqKXNlcnZldXItPmhfYWRkcl9saXN0OwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyID0gKmFkZHJfbGlzdFswXTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwoKICAgIC8qIDQuIENvbm5leGlvbiBhdSBzZXJ2ZXVyICovCiAgICBpZiAoY29ubmVjdChzb2NrX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjb25uZWN0Iik7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIHByaW50ZigiQ29ubmVjdMOpIGF1IHNlcnZldXIgJXM6JWRcbiIsIGFyZ3ZbMV0sIFBPUlQpOwogICAgcHJpbnRmKCJBZHJlc3NlIElQIDogJXNcbiIsIGluZXRfbnRvYShhZHJlc3NlX3NlcnZldXIuc2luX2FkZHIpKTsKCiAgICAvKiA1LiDDiWNoYW5nZSBkZSBkb25uw6llcyAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgICBwcmludGYoIk1lc3NhZ2Ugw6AgZW52b3llciAob3UgJ3F1aXQnIHBvdXIgcXVpdHRlcikgOiAiKTsKICAgICAgICBmZ2V0cyhtZXNzYWdlLCBCVUZGRVJfU0laRSwgc3RkaW4pOwogICAgICAgIAogICAgICAgIC8qIFN1cHByZXNzaW9uIGR1IHNhdXQgZGUgbGlnbmUgKi8KICAgICAgICBtZXNzYWdlW3N0cmNzcG4obWVzc2FnZSwgIlxuIildID0gJ1wwJzsKICAgICAgICAKICAgICAgICBpZiAoc3RyY21wKG1lc3NhZ2UsICJxdWl0IikgPT0gMCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogRW52b2kgKi8KICAgICAgICBzZW5kKHNvY2tfZmQsIG1lc3NhZ2UsIHN0cmxlbihtZXNzYWdlKSwgMCk7CiAgICAgICAgCiAgICAgICAgLyogUsOpY2VwdGlvbiBkZSBsYSByw6lwb25zZSAqLwogICAgICAgIGJ5dGVzX3JlY3VzID0gcmVjdihzb2NrX2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCk7CiAgICAgICAgaWYgKGJ5dGVzX3JlY3VzICZsdDs9IDApIHsKICAgICAgICAgICAgcHJpbnRmKCJTZXJ2ZXVyIGTDqWNvbm5lY3TDqVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBidWZmZXJbYnl0ZXNfcmVjdXNdID0gJ1wwJzsKICAgICAgICBwcmludGYoIlLDqXBvbnNlIGR1IHNlcnZldXIgOiAlc1xuIiwgYnVmZmVyKTsKICAgIH0KCiAgICAvKiA2LiBGZXJtZXR1cmUgKi8KICAgIGNsb3NlKHNvY2tfZmQpOwogICAgcmV0dXJuIDA7Cn08L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3jRQjaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CiNpbmNsdWRlIDxuZXRkYi5oPgoKI2RlZmluZSBQT1JUIDg4ODgKI2RlZmluZSBCVUZGRVJfU0laRSAxMDI0CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CiAgICBpbnQgc29ja19mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXI7CiAgICBzdHJ1Y3QgaG9zdGVudCAqc2VydmV1cjsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGNoYXIgbWVzc2FnZVtCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfcmVjdXM7CiAgICBzdHJ1Y3QgaW5fYWRkciAqKmFkZHJfbGlzdDsgIC8qIFBvdXIgdW5lIHZlcnNpb24gcGx1cyBleHBsaWNpdGUgKi8KCiAgICAvKiBWw6lyaWZpY2F0aW9uIGRlcyBhcmd1bWVudHMgKi8KICAgIGlmIChhcmdjIDwgMikgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6ICVzIDxhZHJlc3NlX3NlcnZldXI+XG4iLCBhcmd2WzBdKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogMS4gQ3LDqWF0aW9uIGR1IHNvY2tldCAqLwogICAgc29ja19mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc29ja19mZCA8IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjcsOpYXRpb24gc29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDIuIFLDqXNvbHV0aW9uIGR1IG5vbSBkJ2jDtHRlICovCiAgICBzZXJ2ZXVyID0gZ2V0aG9zdGJ5bmFtZShhcmd2WzFdKTsKICAgIGlmIChzZXJ2ZXVyID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkjDtHRlIGluY29ubnUgOiAlc1xuIiwgYXJndlsxXSk7CiAgICAgICAgY2xvc2Uoc29ja19mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIDMuIENvbmZpZ3VyYXRpb24gZGUgbCdhZHJlc3NlICovCiAgICBtZW1zZXQoJmFkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgCiAgICAvKiBNw6l0aG9kZSBhbHRlcm5hdGl2ZSBwbHVzIGV4cGxpY2l0ZSAqLwogICAgYWRkcl9saXN0ID0gKHN0cnVjdCBpbl9hZGRyICoqKXNlcnZldXItPmhfYWRkcl9saXN0OwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyID0gKmFkZHJfbGlzdFswXTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwoKICAgIC8qIDQuIENvbm5leGlvbiBhdSBzZXJ2ZXVyICovCiAgICBpZiAoY29ubmVjdChzb2NrX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFkcmVzc2Vfc2VydmV1ciwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpIDwgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNvbm5lY3QiKTsKICAgICAgICBjbG9zZShzb2NrX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgcHJpbnRmKCJDb25uZWN0w6kgYXUgc2VydmV1ciAlczolZFxuIiwgYXJndlsxXSwgUE9SVCk7CiAgICBwcmludGYoIkFkcmVzc2UgSVAgOiAlc1xuIiwgaW5ldF9udG9hKGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkcikpOwoKICAgIC8qIDUuIMOJY2hhbmdlIGRlIGRvbm7DqWVzICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIHByaW50ZigiTWVzc2FnZSDDoCBlbnZveWVyIChvdSAncXVpdCcgcG91ciBxdWl0dGVyKSA6ICIpOwogICAgICAgIGZnZXRzKG1lc3NhZ2UsIEJVRkZFUl9TSVpFLCBzdGRpbik7CiAgICAgICAgCiAgICAgICAgLyogU3VwcHJlc3Npb24gZHUgc2F1dCBkZSBsaWduZSAqLwogICAgICAgIG1lc3NhZ2Vbc3RyY3NwbihtZXNzYWdlLCAiXG4iKV0gPSAnXDAnOwogICAgICAgIAogICAgICAgIGlmIChzdHJjbXAobWVzc2FnZSwgInF1aXQiKSA9PSAwKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKiBFbnZvaSAqLwogICAgICAgIHNlbmQoc29ja19mZCwgbWVzc2FnZSwgc3RybGVuKG1lc3NhZ2UpLCAwKTsKICAgICAgICAKICAgICAgICAvKiBSw6ljZXB0aW9uIGRlIGxhIHLDqXBvbnNlICovCiAgICAgICAgYnl0ZXNfcmVjdXMgPSByZWN2KHNvY2tfZmQsIGJ1ZmZlciwgQlVGRkVSX1NJWkUgLSAxLCAwKTsKICAgICAgICBpZiAoYnl0ZXNfcmVjdXMgPD0gMCkgewogICAgICAgICAgICBwcmludGYoIlNlcnZldXIgZMOpY29ubmVjdMOpXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJ1ZmZlcltieXRlc19yZWN1c10gPSAnXDAnOwogICAgICAgIHByaW50ZigiUsOpcG9uc2UgZHUgc2VydmV1ciA6ICVzXG4iLCBidWZmZXIpOwogICAgfQoKICAgIC8qIDYuIEZlcm1ldHVyZSAqLwogICAgY2xvc2Uoc29ja19mZCk7CiAgICByZXR1cm4gMDsKfXcBY3cAdwB3AHcAdwB3AHl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyRkNmNlYjhiMC0wOWRhLTQ2NzEtYTA4My0zMTQyY2YxYmZjMjV4dzo8aDMgaWQ9Im1ha2VmaWxlLTEiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5NYWtlZmlsZTwvaDM+dwxjb3JlL2hlYWRpbmd9A3cKbWFrZWZpbGUtMXl5eXl5dQB5dwB9kAZ9AHcEZWFzZXl3AHcDdG9weX0AdyQ1MzZiN2VmOS0yZGRkLTRiNzctYTUyNy1hOTliZTk5ZWZmZGV4d4IDPHByZSBjbGFzcz0iRW5saWdodGVySlNSQVciIGRhdGEtZW5saWdodGVyLWxhbmd1YWdlPSJtZCIgZGF0YS1lbmxpZ2h0ZXItdGhlbWU9IiIgZGF0YS1lbmxpZ2h0ZXItaGlnaGxpZ2h0PSIiIGRhdGEtZW5saWdodGVyLWxpbmVudW1iZXJzPSIiIGRhdGEtZW5saWdodGVyLWxpbmVvZmZzZXQ9IiIgZGF0YS1lbmxpZ2h0ZXItdGl0bGU9IiIgZGF0YS1lbmxpZ2h0ZXItZ3JvdXA9IiI+Q0MgPSBnY2MKQ0ZMQUdTID0gLVdhbGwgLVdleHRyYSAtYW5zaSAtcGVkYW50aWMKCmFsbDogY2xpZW50CgpjbGllbnQ6IGNsaWVudF90Y3AuYwoJJChDQykgJChDRkxBR1MpIC1vIGNsaWVudCBjbGllbnRfdGNwLmMKCmNsZWFuOgoJcm0gLWYgY2xpZW50CgouUEhPTlk6IGFsbCBjbGVhbgo8L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3pAFDQyA9IGdjYwpDRkxBR1MgPSAtV2FsbCAtV2V4dHJhIC1hbnNpIC1wZWRhbnRpYwoKYWxsOiBjbGllbnQKCmNsaWVudDogY2xpZW50X3RjcC5jCgkkKENDKSAkKENGTEFHUykgLW8gY2xpZW50IGNsaWVudF90Y3AuYwoKY2xlYW46CglybSAtZiBjbGllbnQKCi5QSE9OWTogYWxsIGNsZWFuCncCbWR3AHcAdwB3AHcAdwB5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHckMTYxMjRkODAtOTc3OC00MTIzLWIyZDAtMDg1MGI4ZTk5YjZheHdMPGgyIGlkPSJtdXRpLXNlcnZldXItZm9yayIgY2xhc3M9IndwLWJsb2NrLWhlYWRpbmciPk11dGlfc2VydmV1ciAoZm9yayk8L2gyPncMY29yZS9oZWFkaW5nfQJ3EW11dGktc2VydmV1ci1mb3JreXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JDhmMDljMGQ0LWQ5ZTMtNDQ3NC04MWIwLWMyYTYzY2QxYjNmNXh3kCg8cHJlIGNsYXNzPSJFbmxpZ2h0ZXJKU1JBVyIgZGF0YS1lbmxpZ2h0ZXItbGFuZ3VhZ2U9ImdlbmVyaWMiIGRhdGEtZW5saWdodGVyLXRoZW1lPSIiIGRhdGEtZW5saWdodGVyLWhpZ2hsaWdodD0iIiBkYXRhLWVubGlnaHRlci1saW5lbnVtYmVycz0iIiBkYXRhLWVubGlnaHRlci1saW5lb2Zmc2V0PSIiIGRhdGEtZW5saWdodGVyLXRpdGxlPSIiIGRhdGEtZW5saWdodGVyLWdyb3VwPSIiPiNpbmNsdWRlICZsdDtzdGRpby5oPgojaW5jbHVkZSAmbHQ7c3RkbGliLmg+CiNpbmNsdWRlICZsdDtzdHJpbmcuaD4KI2luY2x1ZGUgJmx0O3VuaXN0ZC5oPgojaW5jbHVkZSAmbHQ7c3lzL3R5cGVzLmg+CiNpbmNsdWRlICZsdDtzeXMvc29ja2V0Lmg+CiNpbmNsdWRlICZsdDtzeXMvd2FpdC5oPgojaW5jbHVkZSAmbHQ7bmV0aW5ldC9pbi5oPgojaW5jbHVkZSAmbHQ7YXJwYS9pbmV0Lmg+CiNpbmNsdWRlICZsdDtzaWduYWwuaD4KCiNkZWZpbmUgUE9SVCA4ODg4CiNkZWZpbmUgQlVGRkVSX1NJWkUgMTAyNAojZGVmaW5lIE1BWF9DTElFTlRTIDEwCgovKiBHZXN0aW9ubmFpcmUgZGUgc2lnbmF1eCBwb3VyIMOpdml0ZXIgbGVzIHByb2Nlc3N1cyB6b21iaWVzICovCnZvaWQgZ2VzdGlvbm5haXJlX3NpZ2NobGQoaW50IHNpZ25vKSB7CiAgICAvKiB3YWl0cGlkIGF2ZWMgV05PSEFORyBwb3VyIG5lIHBhcyBibG9xdWVyICovCiAgICB3aGlsZSAod2FpdHBpZCgtMSwgTlVMTCwgV05PSEFORykgPiAwKTsKfQoKLyogRm9uY3Rpb24gcG91ciB0cmFpdGVyIGNoYXF1ZSBjbGllbnQgKi8Kdm9pZCB0cmFpdGVyX2NsaWVudChpbnQgY2xpZW50X2ZkLCBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9jbGllbnQpIHsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGludCBieXRlc19sdXM7CiAgICBpbnQgaTsKICAgIGNoYXIgY2xpZW50X2lwW0lORVRfQUREUlNUUkxFTl07CiAgICAKICAgIC8qIENvbnZlcnRpciBsJ2FkcmVzc2UgSVAgZW4gY2hhw65uZSAqLwogICAgaW5ldF9udG9wKEFGX0lORVQsICZhbXA7YWRyZXNzZV9jbGllbnQuc2luX2FkZHIsIGNsaWVudF9pcCwgSU5FVF9BRERSU1RSTEVOKTsKICAgIHByaW50ZigiW1Byb2Nlc3N1cyAlZF0gQ2xpZW50IGNvbm5lY3TDqSA6ICVzOiVkXG4iLCAKICAgICAgICAgICBnZXRwaWQoKSwgCiAgICAgICAgICAgY2xpZW50X2lwLCAKICAgICAgICAgICBudG9ocyhhZHJlc3NlX2NsaWVudC5zaW5fcG9ydCkpOwogICAgCiAgICAvKiBDb21tdW5pY2F0aW9uIGF2ZWMgbGUgY2xpZW50ICovCiAgICB3aGlsZSAoKGJ5dGVzX2x1cyA9IHJlY3YoY2xpZW50X2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCkpID4gMCkgewogICAgICAgIGJ1ZmZlcltieXRlc19sdXNdID0gJ1wwJzsKICAgICAgICBwcmludGYoIltQcm9jZXNzdXMgJWRdIFJlw6d1IDogJXMiLCBnZXRwaWQoKSwgYnVmZmVyKTsKICAgICAgICAKICAgICAgICAvKiBDb252ZXJzaW9uIGVuIG1hanVzY3VsZXMgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpICZsdDsgYnl0ZXNfbHVzOyBpKyspIHsKICAgICAgICAgICAgaWYgKGJ1ZmZlcltpXSA+PSAnYScgJmFtcDsmYW1wOyBidWZmZXJbaV0gJmx0Oz0gJ3onKSB7CiAgICAgICAgICAgICAgICBidWZmZXJbaV0gPSBidWZmZXJbaV0gLSAnYScgKyAnQSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogRW52b2kgZGUgbGEgcsOpcG9uc2UgKi8KICAgICAgICBzZW5kKGNsaWVudF9mZCwgYnVmZmVyLCBieXRlc19sdXMsIDApOwogICAgfQogICAgCiAgICBpZiAoYnl0ZXNfbHVzID09IDApIHsKICAgICAgICBwcmludGYoIltQcm9jZXNzdXMgJWRdIENsaWVudCBkw6ljb25uZWN0w6lcbiIsIGdldHBpZCgpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcGVycm9yKCJbUHJvY2Vzc3VzICVkXSBFcnJldXIgcmVjdiIpOwogICAgfQogICAgCiAgICBjbG9zZShjbGllbnRfZmQpOwogICAgcHJpbnRmKCJbUHJvY2Vzc3VzICVkXSBDb25uZXhpb24gZmVybcOpZSwgcHJvY2Vzc3VzIHRlcm1pbmVcbiIsIGdldHBpZCgpKTsKICAgIGV4aXQoMCk7ICAvKiBMZSBwcm9jZXNzdXMgZmlscyBzZSB0ZXJtaW5lICovCn0KCmludCBtYWluKHZvaWQpIHsKICAgIGludCBzZXJ2ZXVyX2ZkLCBjbGllbnRfZmQ7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9zZXJ2ZXVyLCBhZHJlc3NlX2NsaWVudDsKICAgIHNvY2tsZW5fdCB0YWlsbGVfY2xpZW50ID0gc2l6ZW9mKGFkcmVzc2VfY2xpZW50KTsKICAgIHN0cnVjdCBzaWdhY3Rpb24gc2E7CiAgICBpbnQgb3B0ID0gMTsKICAgIAogICAgLyogMS4gQ29uZmlndXJhdGlvbiBkdSBnZXN0aW9ubmFpcmUgZGUgc2lnbmF1eCBwb3VyIMOpdml0ZXIgbGVzIHpvbWJpZXMgKi8KICAgIHNhLnNhX2hhbmRsZXIgPSBnZXN0aW9ubmFpcmVfc2lnY2hsZDsKICAgIHNpZ2VtcHR5c2V0KCZhbXA7c2Euc2FfbWFzayk7CiAgICBzYS5zYV9mbGFncyA9IFNBX1JFU1RBUlQ7ICAvKiBSw6lpbml0aWFsaXNlciBsZXMgYXBwZWxzIHN5c3TDqG1lIGludGVycm9tcHVzICovCiAgICBpZiAoc2lnYWN0aW9uKFNJR0NITEQsICZhbXA7c2EsIE5VTEwpID09IC0xKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgc2lnYWN0aW9uIik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiAyLiBDcsOpYXRpb24gZHUgc29ja2V0ICovCiAgICBzZXJ2ZXVyX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzZXJ2ZXVyX2ZkICZsdDsgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNyw6lhdGlvbiBzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIDMuIE9wdGlvbiBwb3VyIHLDqXV0aWxpc2VyIGwnYWRyZXNzZSAow6l2aXRlICJBZGRyZXNzIGFscmVhZHkgaW4gdXNlIikgKi8KICAgIGlmIChzZXRzb2Nrb3B0KHNlcnZldXJfZmQsIFNPTF9TT0NLRVQsIFNPX1JFVVNFQUREUiwgJmFtcDtvcHQsIHNpemVvZihvcHQpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBzZXRzb2Nrb3B0Iik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiA0LiBDb25maWd1cmF0aW9uIGRlIGwnYWRyZXNzZSBkdSBzZXJ2ZXVyICovCiAgICBtZW1zZXQoJmFtcDthZHJlc3NlX3NlcnZldXIsIDAsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkci5zX2FkZHIgPSBJTkFERFJfQU5ZOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9wb3J0ID0gaHRvbnMoUE9SVCk7CiAgICAKICAgIC8qIDUuIEF0dGFjaGVtZW50IGR1IHNvY2tldCAqLwogICAgaWYgKGJpbmQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSkgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgYmluZCIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogNi4gTWlzZSBlbiDDqWNvdXRlICovCiAgICBpZiAobGlzdGVuKHNlcnZldXJfZmQsIE1BWF9DTElFTlRTKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBsaXN0ZW4iKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIHByaW50ZigiU2VydmV1ciBtdWx0aS1jbGllbnRzIGTDqW1hcnLDqSBzdXIgbGUgcG9ydCAlZFxuIiwgUE9SVCk7CiAgICBwcmludGYoIlBJRCBkdSBzZXJ2ZXVyIHByaW5jaXBhbCA6ICVkXG4iLCBnZXRwaWQoKSk7CiAgICBwcmludGYoIkVuIGF0dGVudGUgZGUgY29ubmV4aW9ucy4uLlxuXG4iKTsKICAgIAogICAgLyogNy4gQm91Y2xlIHByaW5jaXBhbGUgZCdhY2NlcHRhdGlvbiAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgICAvKiBBY2NlcHRlciB1bmUgbm91dmVsbGUgY29ubmV4aW9uICovCiAgICAgICAgY2xpZW50X2ZkID0gYWNjZXB0KHNlcnZldXJfZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikmYW1wO2FkcmVzc2VfY2xpZW50LCAmYW1wO3RhaWxsZV9jbGllbnQpOwogICAgICAgIGlmIChjbGllbnRfZmQgJmx0OyAwKSB7CiAgICAgICAgICAgIHBlcnJvcigiRXJyZXVyIGFjY2VwdCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogQ3LDqWF0aW9uIGQndW4gcHJvY2Vzc3VzIGZpbHMgcG91ciBnw6lyZXIgbGUgY2xpZW50ICovCiAgICAgICAgcGlkX3QgcGlkID0gZm9yaygpOwogICAgICAgIAogICAgICAgIGlmIChwaWQgJmx0OyAwKSB7CiAgICAgICAgICAgIHBlcnJvcigiRXJyZXVyIGZvcmsiKTsKICAgICAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChwaWQgPT0gMCkgewogICAgICAgICAgICAvKiBQcm9jZXNzdXMgZmlscyAqLwogICAgICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsgIC8qIExlIGZpbHMgbidhIHBhcyBiZXNvaW4gZHUgc29ja2V0IGQnw6ljb3V0ZSAqLwogICAgICAgICAgICB0cmFpdGVyX2NsaWVudChjbGllbnRfZmQsIGFkcmVzc2VfY2xpZW50KTsKICAgICAgICAgICAgLyogTmUgamFtYWlzIGFycml2ZXIgaWNpICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogUHJvY2Vzc3VzIHDDqHJlICovCiAgICAgICAgICAgIGNsb3NlKGNsaWVudF9mZCk7ICAgLyogTGUgcMOocmUgbidhIHBhcyBiZXNvaW4gZHUgc29ja2V0IGNsaWVudCAqLwogICAgICAgICAgICBwcmludGYoIltQw6hyZSAlZF0gTm91dmVhdSBjbGllbnQgY29ubmVjdMOpLCBwcm9jZXNzdXMgZmlscyBjcsOpw6kgOiAlZFxuIiwgCiAgICAgICAgICAgICAgICAgICBnZXRwaWQoKSwgcGlkKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qIDguIEZlcm1ldHVyZSAoamFtYWlzIGF0dGVpbnQgZGFucyBjZXQgZXhlbXBsZSkgKi8KICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgcmV0dXJuIDA7Cn08L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3zyUjaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8c3lzL3dhaXQuaD4KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CgojZGVmaW5lIFBPUlQgODg4OAojZGVmaW5lIEJVRkZFUl9TSVpFIDEwMjQKI2RlZmluZSBNQVhfQ0xJRU5UUyAxMAoKLyogR2VzdGlvbm5haXJlIGRlIHNpZ25hdXggcG91ciDDqXZpdGVyIGxlcyBwcm9jZXNzdXMgem9tYmllcyAqLwp2b2lkIGdlc3Rpb25uYWlyZV9zaWdjaGxkKGludCBzaWdubykgewogICAgLyogd2FpdHBpZCBhdmVjIFdOT0hBTkcgcG91ciBuZSBwYXMgYmxvcXVlciAqLwogICAgd2hpbGUgKHdhaXRwaWQoLTEsIE5VTEwsIFdOT0hBTkcpID4gMCk7Cn0KCi8qIEZvbmN0aW9uIHBvdXIgdHJhaXRlciBjaGFxdWUgY2xpZW50ICovCnZvaWQgdHJhaXRlcl9jbGllbnQoaW50IGNsaWVudF9mZCwgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2VfY2xpZW50KSB7CiAgICBjaGFyIGJ1ZmZlcltCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfbHVzOwogICAgaW50IGk7CiAgICBjaGFyIGNsaWVudF9pcFtJTkVUX0FERFJTVFJMRU5dOwogICAgCiAgICAvKiBDb252ZXJ0aXIgbCdhZHJlc3NlIElQIGVuIGNoYcOubmUgKi8KICAgIGluZXRfbnRvcChBRl9JTkVULCAmYWRyZXNzZV9jbGllbnQuc2luX2FkZHIsIGNsaWVudF9pcCwgSU5FVF9BRERSU1RSTEVOKTsKICAgIHByaW50ZigiW1Byb2Nlc3N1cyAlZF0gQ2xpZW50IGNvbm5lY3TDqSA6ICVzOiVkXG4iLCAKICAgICAgICAgICBnZXRwaWQoKSwgCiAgICAgICAgICAgY2xpZW50X2lwLCAKICAgICAgICAgICBudG9ocyhhZHJlc3NlX2NsaWVudC5zaW5fcG9ydCkpOwogICAgCiAgICAvKiBDb21tdW5pY2F0aW9uIGF2ZWMgbGUgY2xpZW50ICovCiAgICB3aGlsZSAoKGJ5dGVzX2x1cyA9IHJlY3YoY2xpZW50X2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCkpID4gMCkgewogICAgICAgIGJ1ZmZlcltieXRlc19sdXNdID0gJ1wwJzsKICAgICAgICBwcmludGYoIltQcm9jZXNzdXMgJWRdIFJlw6d1IDogJXMiLCBnZXRwaWQoKSwgYnVmZmVyKTsKICAgICAgICAKICAgICAgICAvKiBDb252ZXJzaW9uIGVuIG1hanVzY3VsZXMgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYnl0ZXNfbHVzOyBpKyspIHsKICAgICAgICAgICAgaWYgKGJ1ZmZlcltpXSA+PSAnYScgJiYgYnVmZmVyW2ldIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnVmZmVyW2ldID0gYnVmZmVyW2ldIC0gJ2EnICsgJ0EnOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8qIEVudm9pIGRlIGxhIHLDqXBvbnNlICovCiAgICAgICAgc2VuZChjbGllbnRfZmQsIGJ1ZmZlciwgYnl0ZXNfbHVzLCAwKTsKICAgIH0KICAgIAogICAgaWYgKGJ5dGVzX2x1cyA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJbUHJvY2Vzc3VzICVkXSBDbGllbnQgZMOpY29ubmVjdMOpXG4iLCBnZXRwaWQoKSk7CiAgICB9IGVsc2UgewogICAgICAgIHBlcnJvcigiW1Byb2Nlc3N1cyAlZF0gRXJyZXVyIHJlY3YiKTsKICAgIH0KICAgIAogICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgIHByaW50ZigiW1Byb2Nlc3N1cyAlZF0gQ29ubmV4aW9uIGZlcm3DqWUsIHByb2Nlc3N1cyB0ZXJtaW5lXG4iLCBnZXRwaWQoKSk7CiAgICBleGl0KDApOyAgLyogTGUgcHJvY2Vzc3VzIGZpbHMgc2UgdGVybWluZSAqLwp9CgppbnQgbWFpbih2b2lkKSB7CiAgICBpbnQgc2VydmV1cl9mZCwgY2xpZW50X2ZkOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2Vfc2VydmV1ciwgYWRyZXNzZV9jbGllbnQ7CiAgICBzb2NrbGVuX3QgdGFpbGxlX2NsaWVudCA9IHNpemVvZihhZHJlc3NlX2NsaWVudCk7CiAgICBzdHJ1Y3Qgc2lnYWN0aW9uIHNhOwogICAgaW50IG9wdCA9IDE7CiAgICAKICAgIC8qIDEuIENvbmZpZ3VyYXRpb24gZHUgZ2VzdGlvbm5haXJlIGRlIHNpZ25hdXggcG91ciDDqXZpdGVyIGxlcyB6b21iaWVzICovCiAgICBzYS5zYV9oYW5kbGVyID0gZ2VzdGlvbm5haXJlX3NpZ2NobGQ7CiAgICBzaWdlbXB0eXNldCgmc2Euc2FfbWFzayk7CiAgICBzYS5zYV9mbGFncyA9IFNBX1JFU1RBUlQ7ICAvKiBSw6lpbml0aWFsaXNlciBsZXMgYXBwZWxzIHN5c3TDqG1lIGludGVycm9tcHVzICovCiAgICBpZiAoc2lnYWN0aW9uKFNJR0NITEQsICZzYSwgTlVMTCkgPT0gLTEpIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBzaWdhY3Rpb24iKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIDIuIENyw6lhdGlvbiBkdSBzb2NrZXQgKi8KICAgIHNlcnZldXJfZmQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApOwogICAgaWYgKHNlcnZldXJfZmQgPCAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgY3LDqWF0aW9uIHNvY2tldCIpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogMy4gT3B0aW9uIHBvdXIgcsOpdXRpbGlzZXIgbCdhZHJlc3NlICjDqXZpdGUgIkFkZHJlc3MgYWxyZWFkeSBpbiB1c2UiKSAqLwogICAgaWYgKHNldHNvY2tvcHQoc2VydmV1cl9mZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAmb3B0LCBzaXplb2Yob3B0KSkgPCAwKSB7CiAgICAgICAgcGVycm9yKCJFcnJldXIgc2V0c29ja29wdCIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogNC4gQ29uZmlndXJhdGlvbiBkZSBsJ2FkcmVzc2UgZHUgc2VydmV1ciAqLwogICAgbWVtc2V0KCZhZHJlc3NlX3NlcnZldXIsIDAsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkci5zX2FkZHIgPSBJTkFERFJfQU5ZOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9wb3J0ID0gaHRvbnMoUE9SVCk7CiAgICAKICAgIC8qIDUuIEF0dGFjaGVtZW50IGR1IHNvY2tldCAqLwogICAgaWYgKGJpbmQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSA8IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBiaW5kIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiA2LiBNaXNlIGVuIMOpY291dGUgKi8KICAgIGlmIChsaXN0ZW4oc2VydmV1cl9mZCwgTUFYX0NMSUVOVFMpIDwgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGxpc3RlbiIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgcHJpbnRmKCJTZXJ2ZXVyIG11bHRpLWNsaWVudHMgZMOpbWFycsOpIHN1ciBsZSBwb3J0ICVkXG4iLCBQT1JUKTsKICAgIHByaW50ZigiUElEIGR1IHNlcnZldXIgcHJpbmNpcGFsIDogJWRcbiIsIGdldHBpZCgpKTsKICAgIHByaW50ZigiRW4gYXR0ZW50ZSBkZSBjb25uZXhpb25zLi4uXG5cbiIpOwogICAgCiAgICAvKiA3LiBCb3VjbGUgcHJpbmNpcGFsZSBkJ2FjY2VwdGF0aW9uICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIC8qIEFjY2VwdGVyIHVuZSBub3V2ZWxsZSBjb25uZXhpb24gKi8KICAgICAgICBjbGllbnRfZmQgPSBhY2NlcHQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhZHJlc3NlX2NsaWVudCwgJnRhaWxsZV9jbGllbnQpOwogICAgICAgIGlmIChjbGllbnRfZmQgPCAwKSB7CiAgICAgICAgICAgIHBlcnJvcigiRXJyZXVyIGFjY2VwdCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogQ3LDqWF0aW9uIGQndW4gcHJvY2Vzc3VzIGZpbHMgcG91ciBnw6lyZXIgbGUgY2xpZW50ICovCiAgICAgICAgcGlkX3QgcGlkID0gZm9yaygpOwogICAgICAgIAogICAgICAgIGlmIChwaWQgPCAwKSB7CiAgICAgICAgICAgIHBlcnJvcigiRXJyZXVyIGZvcmsiKTsKICAgICAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChwaWQgPT0gMCkgewogICAgICAgICAgICAvKiBQcm9jZXNzdXMgZmlscyAqLwogICAgICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsgIC8qIExlIGZpbHMgbidhIHBhcyBiZXNvaW4gZHUgc29ja2V0IGQnw6ljb3V0ZSAqLwogICAgICAgICAgICB0cmFpdGVyX2NsaWVudChjbGllbnRfZmQsIGFkcmVzc2VfY2xpZW50KTsKICAgICAgICAgICAgLyogTmUgamFtYWlzIGFycml2ZXIgaWNpICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogUHJvY2Vzc3VzIHDDqHJlICovCiAgICAgICAgICAgIGNsb3NlKGNsaWVudF9mZCk7ICAgLyogTGUgcMOocmUgbidhIHBhcyBiZXNvaW4gZHUgc29ja2V0IGNsaWVudCAqLwogICAgICAgICAgICBwcmludGYoIltQw6hyZSAlZF0gTm91dmVhdSBjbGllbnQgY29ubmVjdMOpLCBwcm9jZXNzdXMgZmlscyBjcsOpw6kgOiAlZFxuIiwgCiAgICAgICAgICAgICAgICAgICBnZXRwaWQoKSwgcGlkKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qIDguIEZlcm1ldHVyZSAoamFtYWlzIGF0dGVpbnQgZGFucyBjZXQgZXhlbXBsZSkgKi8KICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgcmV0dXJuIDA7Cn13B2dlbmVyaWN3AHcAdwB3AHcAdwB5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHckYTk4NzE4NWYtNzk4YS00MjU3LTg0YTMtZDExMGU3YzU2MTZleHdBPGgyIGlkPSJzZXJ2ZXVyLWh0dHAiIGNsYXNzPSJ3cC1ibG9jay1oZWFkaW5nIj5TZXJ2ZXVyIGh0dHAgPC9oMj53DGNvcmUvaGVhZGluZ30CdwxzZXJ2ZXVyLWh0dHB5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHckOWZhMzRiNDEtYTkyNi00ODQ5LTgxYzUtZWVlMGE5NTJjYTdkeHeWHjxwcmUgY2xhc3M9IkVubGlnaHRlckpTUkFXIiBkYXRhLWVubGlnaHRlci1sYW5ndWFnZT0iYyIgZGF0YS1lbmxpZ2h0ZXItdGhlbWU9IiIgZGF0YS1lbmxpZ2h0ZXItaGlnaGxpZ2h0PSIiIGRhdGEtZW5saWdodGVyLWxpbmVudW1iZXJzPSIiIGRhdGEtZW5saWdodGVyLWxpbmVvZmZzZXQ9IiIgZGF0YS1lbmxpZ2h0ZXItdGl0bGU9IiIgZGF0YS1lbmxpZ2h0ZXItZ3JvdXA9IiI+Lyogc2VydmV1cl9odHRwX21pbmltYWwuYyAtIFZlcnNpb24gc2ltcGxpZmnDqWUgcG91ciB0ZXN0ZXIgKi8KI2luY2x1ZGUgJmx0O3N0ZGlvLmg+CiNpbmNsdWRlICZsdDtzdGRsaWIuaD4KI2luY2x1ZGUgJmx0O3N0cmluZy5oPgojaW5jbHVkZSAmbHQ7dW5pc3RkLmg+CiNpbmNsdWRlICZsdDtzeXMvdHlwZXMuaD4KI2luY2x1ZGUgJmx0O3N5cy9zb2NrZXQuaD4KI2luY2x1ZGUgJmx0O25ldGluZXQvaW4uaD4KI2luY2x1ZGUgJmx0O2FycGEvaW5ldC5oPgoKI2RlZmluZSBQT1JUIDgwODAKI2RlZmluZSBCVUZGRVJfU0laRSA0MDk2CgppbnQgbWFpbih2b2lkKSB7CiAgICBpbnQgc2VydmV1cl9mZCwgY2xpZW50X2ZkOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2Vfc2VydmV1ciwgYWRyZXNzZV9jbGllbnQ7CiAgICBzb2NrbGVuX3QgdGFpbGxlX2NsaWVudCA9IHNpemVvZihhZHJlc3NlX2NsaWVudCk7CiAgICBjaGFyIGJ1ZmZlcltCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfbHVzOwogICAgY2hhciAqcmVwb25zZV9vayA9ICJIVFRQLzEuMSAyMDAgT0tcclxuIgogICAgICAgICAgICAgICAgICAgICAgICJDb250ZW50LVR5cGU6IHRleHQvaHRtbFxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQtTGVuZ3RoOiAxMzVcclxuIgogICAgICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uOiBjbG9zZVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIlxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIiZsdDshRE9DVFlQRSBodG1sPlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7aHRtbD5cbiIKICAgICAgICAgICAgICAgICAgICAgICAiJmx0O2hlYWQ+Jmx0O3RpdGxlPlRlc3QgU2VydmV1ciZsdDsvdGl0bGU+Jmx0Oy9oZWFkPlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7Ym9keT5cbiIKICAgICAgICAgICAgICAgICAgICAgICAiJmx0O2gxPkJpZW52ZW51ZSBzdXIgbW9uIHNlcnZldXIgSFRUUCEmbHQ7L2gxPlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7cD5DZWNpIGVzdCB1bmUgcmVwb25zZSBIVE1MLiZsdDsvcD5cbiIKICAgICAgICAgICAgICAgICAgICAgICAiJmx0Oy9ib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICImbHQ7L2h0bWw+XG4iOwogICAgCiAgICBjaGFyICpyZXBvbnNlXzQwNCA9ICJIVFRQLzEuMSA0MDQgTm90IEZvdW5kXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQtVHlwZTogdGV4dC9odG1sXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQtTGVuZ3RoOiAxMDVcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiQ29ubmVjdGlvbjogY2xvc2VcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAgIiZsdDshRE9DVFlQRSBodG1sPlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiJmx0O2h0bWw+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICImbHQ7Ym9keT5cbiIKICAgICAgICAgICAgICAgICAgICAgICAgIiZsdDtoMT40MDQgLSBQYWdlIG5vbiB0cm91dmVlJmx0Oy9oMT5cbiIKICAgICAgICAgICAgICAgICAgICAgICAgIiZsdDsvYm9keT5cbiIKICAgICAgICAgICAgICAgICAgICAgICAgIiZsdDsvaHRtbD5cbiI7CgogICAgLyogQ3LDqWF0aW9uIHNvY2tldCAqLwogICAgc2VydmV1cl9mZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CiAgICBpZiAoc2VydmV1cl9mZCAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBjcsOpYXRpb24gc29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIENvbmZpZ3VyYXRpb24gKi8KICAgIG1lbXNldCgmYW1wO2FkcmVzc2Vfc2VydmV1ciwgMCwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9hZGRyLnNfYWRkciA9IElOQUREUl9BTlk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX3BvcnQgPSBodG9ucyhQT1JUKTsKCiAgICAvKiBCaW5kICovCiAgICBpZiAoYmluZChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBiaW5kIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIExpc3RlbiAqLwogICAgaWYgKGxpc3RlbihzZXJ2ZXVyX2ZkLCA1KSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBsaXN0ZW4iKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgcHJpbnRmKCJTZXJ2ZXVyIEhUVFAgZW4gw6ljb3V0ZSBzdXIgbGUgcG9ydCAlZFxuIiwgUE9SVCk7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBjbGllbnRfZmQgPSBhY2NlcHQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhbXA7YWRyZXNzZV9jbGllbnQsICZhbXA7dGFpbGxlX2NsaWVudCk7CiAgICAgICAgaWYgKGNsaWVudF9mZCAmbHQ7IDApIHsKICAgICAgICAgICAgcGVycm9yKCJFcnJldXIgYWNjZXB0Iik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgcHJpbnRmKCJDbGllbnQgY29ubmVjdMOpIDogJXM6JWRcbiIsIAogICAgICAgICAgICAgICBpbmV0X250b2EoYWRyZXNzZV9jbGllbnQuc2luX2FkZHIpLCAKICAgICAgICAgICAgICAgbnRvaHMoYWRyZXNzZV9jbGllbnQuc2luX3BvcnQpKTsKCiAgICAgICAgLyogTGlyZSBsYSByZXF1w6p0ZSAob3B0aW9ubmVsLCBvbiBpZ25vcmUgc29uIGNvbnRlbnUpICovCiAgICAgICAgYnl0ZXNfbHVzID0gcmVjdihjbGllbnRfZmQsIGJ1ZmZlciwgQlVGRkVSX1NJWkUgLSAxLCAwKTsKICAgICAgICBpZiAoYnl0ZXNfbHVzID4gMCkgewogICAgICAgICAgICBidWZmZXJbYnl0ZXNfbHVzXSA9ICdcMCc7CiAgICAgICAgICAgIHByaW50ZigiUmVxdcOqdGUgcmXDp3VlOlxuJXNcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBSw6lwb25zZSBzaW1wbGUgKi8KICAgICAgICAgICAgaWYgKHN0cnN0cihidWZmZXIsICJHRVQgLyAiKSB8fCBzdHJzdHIoYnVmZmVyLCAiR0VUIC9pbmRleC5odG1sIikpIHsKICAgICAgICAgICAgICAgIHNlbmQoY2xpZW50X2ZkLCByZXBvbnNlX29rLCBzdHJsZW4ocmVwb25zZV9vayksIDApOwogICAgICAgICAgICAgICAgcHJpbnRmKCJSw6lwb25zZSAyMDAgT0sgZW52b3nDqWVcbiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VuZChjbGllbnRfZmQsIHJlcG9uc2VfNDA0LCBzdHJsZW4ocmVwb25zZV80MDQpLCAwKTsKICAgICAgICAgICAgICAgIHByaW50ZigiUsOpcG9uc2UgNDA0IGVudm95w6llXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICBwcmludGYoIkNvbm5leGlvbiBmZXJtw6llXG5cbiIpOwogICAgfQoKICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgcmV0dXJuIDA7Cn08L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3yRsvKiBzZXJ2ZXVyX2h0dHBfbWluaW1hbC5jIC0gVmVyc2lvbiBzaW1wbGlmacOpZSBwb3VyIHRlc3RlciAqLwojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CgojZGVmaW5lIFBPUlQgODA4MAojZGVmaW5lIEJVRkZFUl9TSVpFIDQwOTYKCmludCBtYWluKHZvaWQpIHsKICAgIGludCBzZXJ2ZXVyX2ZkLCBjbGllbnRfZmQ7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9zZXJ2ZXVyLCBhZHJlc3NlX2NsaWVudDsKICAgIHNvY2tsZW5fdCB0YWlsbGVfY2xpZW50ID0gc2l6ZW9mKGFkcmVzc2VfY2xpZW50KTsKICAgIGNoYXIgYnVmZmVyW0JVRkZFUl9TSVpFXTsKICAgIGludCBieXRlc19sdXM7CiAgICBjaGFyICpyZXBvbnNlX29rID0gIkhUVFAvMS4xIDIwMCBPS1xyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQtVHlwZTogdGV4dC9odG1sXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1MZW5ndGg6IDEzNVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbm5lY3Rpb246IGNsb3NlXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiXHJcbiIKICAgICAgICAgICAgICAgICAgICAgICAiPCFET0NUWVBFIGh0bWw+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIjxodG1sPlxuIgogICAgICAgICAgICAgICAgICAgICAgICI8aGVhZD48dGl0bGU+VGVzdCBTZXJ2ZXVyPC90aXRsZT48L2hlYWQ+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIjxib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICI8aDE+QmllbnZlbnVlIHN1ciBtb24gc2VydmV1ciBIVFRQITwvaDE+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIjxwPkNlY2kgZXN0IHVuZSByZXBvbnNlIEhUTUwuPC9wPlxuIgogICAgICAgICAgICAgICAgICAgICAgICI8L2JvZHk+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgIjwvaHRtbD5cbiI7CiAgICAKICAgIGNoYXIgKnJlcG9uc2VfNDA0ID0gIkhUVFAvMS4xIDQwNCBOb3QgRm91bmRcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1UeXBlOiB0ZXh0L2h0bWxcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudC1MZW5ndGg6IDEwNVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uOiBjbG9zZVxyXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICJcclxuIgogICAgICAgICAgICAgICAgICAgICAgICAiPCFET0NUWVBFIGh0bWw+XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICI8aHRtbD5cbiIKICAgICAgICAgICAgICAgICAgICAgICAgIjxib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiPGgxPjQwNCAtIFBhZ2Ugbm9uIHRyb3V2ZWU8L2gxPlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiPC9ib2R5PlxuIgogICAgICAgICAgICAgICAgICAgICAgICAiPC9odG1sPlxuIjsKCiAgICAvKiBDcsOpYXRpb24gc29ja2V0ICovCiAgICBzZXJ2ZXVyX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzZXJ2ZXVyX2ZkIDwgMCkgewogICAgICAgIHBlcnJvcigiRXJyZXVyIGNyw6lhdGlvbiBzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgLyogQ29uZmlndXJhdGlvbiAqLwogICAgbWVtc2V0KCZhZHJlc3NlX3NlcnZldXIsIDAsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fYWRkci5zX2FkZHIgPSBJTkFERFJfQU5ZOwogICAgYWRyZXNzZV9zZXJ2ZXVyLnNpbl9wb3J0ID0gaHRvbnMoUE9SVCk7CgogICAgLyogQmluZCAqLwogICAgaWYgKGJpbmQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSA8IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBiaW5kIik7CiAgICAgICAgY2xvc2Uoc2VydmV1cl9mZCk7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQoKICAgIC8qIExpc3RlbiAqLwogICAgaWYgKGxpc3RlbihzZXJ2ZXVyX2ZkLCA1KSA8IDApIHsKICAgICAgICBwZXJyb3IoIkVycmV1ciBsaXN0ZW4iKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CgogICAgcHJpbnRmKCJTZXJ2ZXVyIEhUVFAgZW4gw6ljb3V0ZSBzdXIgbGUgcG9ydCAlZFxuIiwgUE9SVCk7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBjbGllbnRfZmQgPSBhY2NlcHQoc2VydmV1cl9mZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZhZHJlc3NlX2NsaWVudCwgJnRhaWxsZV9jbGllbnQpOwogICAgICAgIGlmIChjbGllbnRfZmQgPCAwKSB7CiAgICAgICAgICAgIHBlcnJvcigiRXJyZXVyIGFjY2VwdCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiQ2xpZW50IGNvbm5lY3TDqSA6ICVzOiVkXG4iLCAKICAgICAgICAgICAgICAgaW5ldF9udG9hKGFkcmVzc2VfY2xpZW50LnNpbl9hZGRyKSwgCiAgICAgICAgICAgICAgIG50b2hzKGFkcmVzc2VfY2xpZW50LnNpbl9wb3J0KSk7CgogICAgICAgIC8qIExpcmUgbGEgcmVxdcOqdGUgKG9wdGlvbm5lbCwgb24gaWdub3JlIHNvbiBjb250ZW51KSAqLwogICAgICAgIGJ5dGVzX2x1cyA9IHJlY3YoY2xpZW50X2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCk7CiAgICAgICAgaWYgKGJ5dGVzX2x1cyA+IDApIHsKICAgICAgICAgICAgYnVmZmVyW2J5dGVzX2x1c10gPSAnXDAnOwogICAgICAgICAgICBwcmludGYoIlJlcXXDqnRlIHJlw6d1ZTpcbiVzXG4iLCBidWZmZXIpOwogICAgICAgICAgICAKICAgICAgICAgICAgLyogUsOpcG9uc2Ugc2ltcGxlICovCiAgICAgICAgICAgIGlmIChzdHJzdHIoYnVmZmVyLCAiR0VUIC8gIikgfHwgc3Ryc3RyKGJ1ZmZlciwgIkdFVCAvaW5kZXguaHRtbCIpKSB7CiAgICAgICAgICAgICAgICBzZW5kKGNsaWVudF9mZCwgcmVwb25zZV9vaywgc3RybGVuKHJlcG9uc2Vfb2spLCAwKTsKICAgICAgICAgICAgICAgIHByaW50ZigiUsOpcG9uc2UgMjAwIE9LIGVudm95w6llXG4iKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbmQoY2xpZW50X2ZkLCByZXBvbnNlXzQwNCwgc3RybGVuKHJlcG9uc2VfNDA0KSwgMCk7CiAgICAgICAgICAgICAgICBwcmludGYoIlLDqXBvbnNlIDQwNCBlbnZvecOpZVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICAgICAgcHJpbnRmKCJDb25uZXhpb24gZmVybcOpZVxuXG4iKTsKICAgIH0KCiAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgIHJldHVybiAwOwp9dwFjdwB3AHcAdwB3AHcAeXl5eXl1AHl3AH2QBn0AdwRlYXNleXcAdwN0b3B5fQB3JGQ4YWMwNGU2LTEzYWYtNGE0NS05MDJkLWMzZGJjM2I5YWYzZXh3WjxoMiBpZD0ic2VydmV1ci1odHRwLW11bHRpLWNsaWVudCIgY2xhc3M9IndwLWJsb2NrLWhlYWRpbmciPlNlcnZldXIgaHR0cCBtdWx0aS1jbGllbnQ8L2gyPncMY29yZS9oZWFkaW5nfQJ3GXNlcnZldXItaHR0cC1tdWx0aS1jbGllbnR5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHckZGQzYWUzOTgtOTQwNC00M2M2LTg2OTktNjE0MDYwNGEzYzdjeHe\/QTxwcmUgY2xhc3M9IkVubGlnaHRlckpTUkFXIiBkYXRhLWVubGlnaHRlci1sYW5ndWFnZT0iYyIgZGF0YS1lbmxpZ2h0ZXItdGhlbWU9IiIgZGF0YS1lbmxpZ2h0ZXItaGlnaGxpZ2h0PSIiIGRhdGEtZW5saWdodGVyLWxpbmVudW1iZXJzPSIiIGRhdGEtZW5saWdodGVyLWxpbmVvZmZzZXQ9IiIgZGF0YS1lbmxpZ2h0ZXItdGl0bGU9IiIgZGF0YS1lbmxpZ2h0ZXItZ3JvdXA9IiI+I2luY2x1ZGUgJmx0O3N0ZGlvLmg+CiNpbmNsdWRlICZsdDtzdGRsaWIuaD4KI2luY2x1ZGUgJmx0O3N0cmluZy5oPgojaW5jbHVkZSAmbHQ7dW5pc3RkLmg+CiNpbmNsdWRlICZsdDtzeXMvdHlwZXMuaD4KI2luY2x1ZGUgJmx0O3N5cy9zb2NrZXQuaD4KI2luY2x1ZGUgJmx0O3N5cy93YWl0Lmg+CiNpbmNsdWRlICZsdDtuZXRpbmV0L2luLmg+CiNpbmNsdWRlICZsdDthcnBhL2luZXQuaD4KI2luY2x1ZGUgJmx0O3NpZ25hbC5oPgojaW5jbHVkZSAmbHQ7dGltZS5oPgoKI2RlZmluZSBQT1JUIDgwODAKI2RlZmluZSBCVUZGRVJfU0laRSA0MDk2CiNkZWZpbmUgTUFYX0NMSUVOVFMgMTAwCgppbnQgY2xpZW50c19hY3RpZnMgPSAwOwppbnQgY29tcHRldXJfY2xpZW50cyA9IDA7Cgp2b2lkIGdlc3Rpb25uYWlyZV9zaWdjaGxkKGludCBzaWdubykgewogICAgd2hpbGUgKHdhaXRwaWQoLTEsIE5VTEwsIFdOT0hBTkcpID4gMCkgewogICAgICAgIGNsaWVudHNfYWN0aWZzLS07CiAgICB9Cn0KCi8qIEVudm95ZXIgdW5lIHLDqXBvbnNlIEhUVFAgKi8Kdm9pZCBlbnZveWVyX3JlcG9uc2VfaHR0cChpbnQgY2xpZW50X2ZkLCBjb25zdCBjaGFyICpib2R5KSB7CiAgICBjaGFyIHJlcG9uc2VbQlVGRkVSX1NJWkVdOwogICAgCiAgICBzcHJpbnRmKHJlcG9uc2UsCiAgICAgICAgICAgICJIVFRQLzEuMSAyMDAgT0tcclxuIgogICAgICAgICAgICAiQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLThcclxuIgogICAgICAgICAgICAiQ29udGVudC1MZW5ndGg6ICVsZFxyXG4iCiAgICAgICAgICAgICJDb25uZWN0aW9uOiBjbG9zZVxyXG4iCiAgICAgICAgICAgICJTZXJ2ZXI6IEFOU0ktQy8xLjBcclxuIgogICAgICAgICAgICAiXHJcbiIKICAgICAgICAgICAgIiVzIiwKICAgICAgICAgICAgc3RybGVuKGJvZHkpLCBib2R5KTsKICAgIAogICAgc2VuZChjbGllbnRfZmQsIHJlcG9uc2UsIHN0cmxlbihyZXBvbnNlKSwgMCk7Cn0KCi8qIFBhZ2UgZCdhY2N1ZWlsICovCnZvaWQgZW52b3llcl9hY2N1ZWlsKGludCBjbGllbnRfZmQsIGludCBudW1lcm9fY2xpZW50KSB7CiAgICBjaGFyIGJvZHlbQlVGRkVSX1NJWkVdOwogICAgdGltZV90IG5vdzsKICAgIGNoYXIgZGF0ZV9zdHJbNjRdOwogICAgCiAgICB0aW1lKCZhbXA7bm93KTsKICAgIHN0cmZ0aW1lKGRhdGVfc3RyLCBzaXplb2YoZGF0ZV9zdHIpLCAiJWQvJW0vJVkgJUg6JU06JVMiLCBsb2NhbHRpbWUoJmFtcDtub3cpKTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiJmx0O2h0bWw+XG4iCiAgICAgICAgICAgICImbHQ7aGVhZD5cbiIKICAgICAgICAgICAgIiZsdDt0aXRsZT5TZXJ2ZXVyIEFOU0kgQyZsdDsvdGl0bGU+XG4iCiAgICAgICAgICAgICImbHQ7L2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7Ym9keT5cbiIKICAgICAgICAgICAgIiZsdDtoMT5TZXJ2ZXVyIEFOU0kgQyZsdDsvaDE+XG4iCiAgICAgICAgICAgICImbHQ7aHI+XG4iCiAgICAgICAgICAgICImbHQ7aDI+Q2xpZW50IG51bWVybyA6ICMlZCZsdDsvaDI+XG4iCiAgICAgICAgICAgICImbHQ7cD5DbGllbnRzIGFjdGlmcyA6ICVkJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+VG90YWwgY2xpZW50cyBzZXJ2aXMgOiAlZCZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPkRhdGUvSGV1cmUgOiAlcyZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDtwPlBvcnQgOiAlZCB8IFBJRCA6ICVkJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O2hyPlxuIgogICAgICAgICAgICAiJmx0O3A+Jmx0O2EgaHJlZj0nL3N0YXRzJz5Wb2lyIGxlcyBzdGF0aXN0aXF1ZXMmbHQ7L2E+Jmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+Jmx0O2EgaHJlZj0nL3F1aXQnPlF1aXR0ZXImbHQ7L2E+Jmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0Oy9ib2R5PlxuIgogICAgICAgICAgICAiJmx0Oy9odG1sPlxuIiwKICAgICAgICAgICAgbnVtZXJvX2NsaWVudCwgY2xpZW50c19hY3RpZnMsIGNvbXB0ZXVyX2NsaWVudHMsIGRhdGVfc3RyLCBQT1JULCBnZXRwaWQoKSk7CiAgICAKICAgIGVudm95ZXJfcmVwb25zZV9odHRwKGNsaWVudF9mZCwgYm9keSk7Cn0KCi8qIFBhZ2Ugc3RhdGlzdGlxdWVzICovCnZvaWQgZW52b3llcl9zdGF0cyhpbnQgY2xpZW50X2ZkLCBpbnQgbnVtZXJvX2NsaWVudCkgewogICAgY2hhciBib2R5W0JVRkZFUl9TSVpFXTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiJmx0O2h0bWw+XG4iCiAgICAgICAgICAgICImbHQ7aGVhZD5cbiIKICAgICAgICAgICAgIiZsdDt0aXRsZT5TdGF0aXN0aXF1ZXMmbHQ7L3RpdGxlPlxuIgogICAgICAgICAgICAiJmx0Oy9oZWFkPlxuIgogICAgICAgICAgICAiJmx0O2JvZHk+XG4iCiAgICAgICAgICAgICImbHQ7aDE+U3RhdGlzdGlxdWVzJmx0Oy9oMT5cbiIKICAgICAgICAgICAgIiZsdDtocj5cbiIKICAgICAgICAgICAgIiZsdDtoMj5Wb3RyZSBudW1lcm8gOiAjJWQmbHQ7L2gyPlxuIgogICAgICAgICAgICAiJmx0O3A+Q2xpZW50cyBhY3R1ZWxsZW1lbnQgY29ubmVjdGVzIDogJWQmbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7cD5Ub3RhbCBjbGllbnRzIHNlcnZpcyBkZXB1aXMgZGVtYXJyYWdlIDogJWQmbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7cD5DYXBhY2l0ZSBtYXhpbWFsZSA6ICVkIGNsaWVudHMmbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7aHI+XG4iCiAgICAgICAgICAgICImbHQ7cD4mbHQ7YSBocmVmPScvJz5SZXRvdXIgYWNjdWVpbCZsdDsvYT4mbHQ7L3A+XG4iCiAgICAgICAgICAgICImbHQ7L2JvZHk+XG4iCiAgICAgICAgICAgICImbHQ7L2h0bWw+XG4iLAogICAgICAgICAgICBudW1lcm9fY2xpZW50LCBjbGllbnRzX2FjdGlmcywgY29tcHRldXJfY2xpZW50cywgTUFYX0NMSUVOVFMpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBQYWdlIDQwNCAqLwp2b2lkIGVudm95ZXJfNDA0KGludCBjbGllbnRfZmQpIHsKICAgIGNoYXIgYm9keVtCVUZGRVJfU0laRV07CiAgICAKICAgIHNwcmludGYoYm9keSwKICAgICAgICAgICAgIiZsdDtodG1sPlxuIgogICAgICAgICAgICAiJmx0O2hlYWQ+XG4iCiAgICAgICAgICAgICImbHQ7dGl0bGU+NDA0Jmx0Oy90aXRsZT5cbiIKICAgICAgICAgICAgIiZsdDsvaGVhZD5cbiIKICAgICAgICAgICAgIiZsdDtib2R5PlxuIgogICAgICAgICAgICAiJmx0O2gxPjQwNCAtIFBhZ2Ugbm9uIHRyb3V2ZWUmbHQ7L2gxPlxuIgogICAgICAgICAgICAiJmx0O2hyPlxuIgogICAgICAgICAgICAiJmx0O3A+TGEgcGFnZSBkZW1hbmRlZSBuJ2V4aXN0ZSBwYXMuJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+Jmx0O2EgaHJlZj0nLyc+UmV0b3VyIGFjY3VlaWwmbHQ7L2E+Jmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0Oy9ib2R5PlxuIgogICAgICAgICAgICAiJmx0Oy9odG1sPlxuIik7CiAgICAKICAgIGVudm95ZXJfcmVwb25zZV9odHRwKGNsaWVudF9mZCwgYm9keSk7Cn0KCi8qIFBhZ2UgYXUgcmV2b2lyICovCnZvaWQgZW52b3llcl9hdV9yZXZvaXIoaW50IGNsaWVudF9mZCkgewogICAgY2hhciBib2R5W0JVRkZFUl9TSVpFXTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiJmx0O2h0bWw+XG4iCiAgICAgICAgICAgICImbHQ7aGVhZD5cbiIKICAgICAgICAgICAgIiZsdDt0aXRsZT5BdSByZXZvaXImbHQ7L3RpdGxlPlxuIgogICAgICAgICAgICAiJmx0Oy9oZWFkPlxuIgogICAgICAgICAgICAiJmx0O2JvZHk+XG4iCiAgICAgICAgICAgICImbHQ7aDE+QXUgcmV2b2lyICEmbHQ7L2gxPlxuIgogICAgICAgICAgICAiJmx0O2hyPlxuIgogICAgICAgICAgICAiJmx0O3A+TWVyY2kgZCdhdm9pciB2aXNpdGUgbm90cmUgc2VydmV1ciBBTlNJIEMuJmx0Oy9wPlxuIgogICAgICAgICAgICAiJmx0O3A+Jmx0O2EgaHJlZj0nLyc+Tm91dmVsbGUgY29ubmV4aW9uJmx0Oy9hPiZsdDsvcD5cbiIKICAgICAgICAgICAgIiZsdDsvYm9keT5cbiIKICAgICAgICAgICAgIiZsdDsvaHRtbD5cbiIpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBFeHRyYWlyZSBsZSBjaGVtaW4gZGUgbGEgcmVxdcOqdGUgSFRUUCAqLwp2b2lkIGV4dHJhaXJlX2NoZW1pbihjb25zdCBjaGFyICpyZXF1ZXRlLCBjaGFyICpjaGVtaW4pIHsKICAgIGNoYXIgbWV0aG9kWzE2XTsKICAgIGNoYXIgcGF0aFsyNTZdOwogICAgY2hhciB2ZXJzaW9uWzE2XTsKICAgIAogICAgc3NjYW5mKHJlcXVldGUsICIlcyAlcyAlcyIsIG1ldGhvZCwgcGF0aCwgdmVyc2lvbik7CiAgICBzdHJjcHkoY2hlbWluLCBwYXRoKTsKfQoKdm9pZCB0cmFpdGVyX2NsaWVudChpbnQgY2xpZW50X2ZkLCBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9jbGllbnQsIGludCBudW1lcm9fY2xpZW50KSB7CiAgICBjaGFyIGJ1ZmZlcltCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfbHVzOwogICAgY2hhciBjaGVtaW5bMjU2XTsKICAgIGNoYXIgY2xpZW50X2lwW0lORVRfQUREUlNUUkxFTl07CiAgICAKICAgIGluZXRfbnRvcChBRl9JTkVULCAmYW1wO2FkcmVzc2VfY2xpZW50LnNpbl9hZGRyLCBjbGllbnRfaXAsIElORVRfQUREUlNUUkxFTik7CiAgICAKICAgIHByaW50ZigiW0NsaWVudCAjJWRdIENvbm5lY3RlIGRlcHVpcyAlczolZFxuIiwgCiAgICAgICAgICAgbnVtZXJvX2NsaWVudCwgY2xpZW50X2lwLCBudG9ocyhhZHJlc3NlX2NsaWVudC5zaW5fcG9ydCkpOwogICAgCiAgICAvKiBMaXJlIGxhIHJlcXXDqnRlICovCiAgICBieXRlc19sdXMgPSByZWN2KGNsaWVudF9mZCwgYnVmZmVyLCBCVUZGRVJfU0laRSAtIDEsIDApOwogICAgaWYgKGJ5dGVzX2x1cyAmbHQ7PSAwKSB7CiAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICBleGl0KDApOwogICAgfQogICAgCiAgICBidWZmZXJbYnl0ZXNfbHVzXSA9ICdcMCc7CiAgICBleHRyYWlyZV9jaGVtaW4oYnVmZmVyLCBjaGVtaW4pOwogICAgCiAgICBwcmludGYoIltDbGllbnQgIyVkXSBDaGVtaW46ICVzXG4iLCBudW1lcm9fY2xpZW50LCBjaGVtaW4pOwogICAgCiAgICAvKiBSb3V0ZXIgc2Vsb24gbGUgY2hlbWluICovCiAgICBpZiAoc3RyY21wKGNoZW1pbiwgIi8iKSA9PSAwIHx8IHN0cmNtcChjaGVtaW4sICIvaW5kZXguaHRtbCIpID09IDApIHsKICAgICAgICBlbnZveWVyX2FjY3VlaWwoY2xpZW50X2ZkLCBudW1lcm9fY2xpZW50KTsKICAgIH0KICAgIGVsc2UgaWYgKHN0cmNtcChjaGVtaW4sICIvc3RhdHMiKSA9PSAwKSB7CiAgICAgICAgZW52b3llcl9zdGF0cyhjbGllbnRfZmQsIG51bWVyb19jbGllbnQpOwogICAgfQogICAgZWxzZSBpZiAoc3RyY21wKGNoZW1pbiwgIi9xdWl0IikgPT0gMCkgewogICAgICAgIGVudm95ZXJfYXVfcmV2b2lyKGNsaWVudF9mZCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBlbnZveWVyXzQwNChjbGllbnRfZmQpOwogICAgfQogICAgCiAgICBwcmludGYoIltDbGllbnQgIyVkXSBEZWNvbm5leGlvblxuIiwgbnVtZXJvX2NsaWVudCk7CiAgICBjbG9zZShjbGllbnRfZmQpOwogICAgZXhpdCgwKTsKfQoKaW50IG1haW4odm9pZCkgewogICAgaW50IHNlcnZldXJfZmQsIGNsaWVudF9mZDsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZHJlc3NlX3NlcnZldXIsIGFkcmVzc2VfY2xpZW50OwogICAgc29ja2xlbl90IHRhaWxsZV9jbGllbnQgPSBzaXplb2YoYWRyZXNzZV9jbGllbnQpOwogICAgaW50IG9wdCA9IDE7CiAgICBpbnQgbnVtZXJvX25vdXZlYXVfY2xpZW50OwogICAgCiAgICAvKiBHZXN0aW9uIGRlcyBzaWduYXV4ICovCiAgICBzaWduYWwoU0lHQ0hMRCwgZ2VzdGlvbm5haXJlX3NpZ2NobGQpOwogICAgCiAgICAvKiBDcsOpYXRpb24gc29ja2V0ICovCiAgICBzZXJ2ZXVyX2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKICAgIGlmIChzZXJ2ZXVyX2ZkICZsdDsgMCkgewogICAgICAgIHBlcnJvcigic29ja2V0Iik7CiAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgCiAgICAvKiBPcHRpb24gcmV1c2UgYWRkcmVzcyAqLwogICAgc2V0c29ja29wdChzZXJ2ZXVyX2ZkLCBTT0xfU09DS0VULCBTT19SRVVTRUFERFIsICZhbXA7b3B0LCBzaXplb2Yob3B0KSk7CiAgICAKICAgIC8qIENvbmZpZ3VyYXRpb24gYWRyZXNzZSAqLwogICAgbWVtc2V0KCZhbXA7YWRyZXNzZV9zZXJ2ZXVyLCAwLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2FkZHIuc19hZGRyID0gSU5BRERSX0FOWTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwogICAgCiAgICAvKiBCaW5kICovCiAgICBpZiAoYmluZChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX3NlcnZldXIsIHNpemVvZihhZHJlc3NlX3NlcnZldXIpKSAmbHQ7IDApIHsKICAgICAgICBwZXJyb3IoImJpbmQiKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIExpc3RlbiAqLwogICAgaWYgKGxpc3RlbihzZXJ2ZXVyX2ZkLCBNQVhfQ0xJRU5UUykgJmx0OyAwKSB7CiAgICAgICAgcGVycm9yKCJsaXN0ZW4iKTsKICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIHByaW50ZigiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKTsKICAgIHByaW50ZigiU0VSVkVVUiBIVFRQIEFOU0kgQ1xuIik7CiAgICBwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwogICAgcHJpbnRmKCJQb3J0OiAlZFxuIiwgUE9SVCk7CiAgICBwcmludGYoIlVSTDogaHR0cDovL2xvY2FsaG9zdDolZC9cbiIsIFBPUlQpOwogICAgcHJpbnRmKCJQSUQ6ICVkXG4iLCBnZXRwaWQoKSk7CiAgICBwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuIik7CiAgICAKICAgIC8qIEJvdWNsZSBwcmluY2lwYWxlICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIGNsaWVudF9mZCA9IGFjY2VwdChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFtcDthZHJlc3NlX2NsaWVudCwgJmFtcDt0YWlsbGVfY2xpZW50KTsKICAgICAgICBpZiAoY2xpZW50X2ZkICZsdDsgMCkgewogICAgICAgICAgICBwZXJyb3IoImFjY2VwdCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgY2xpZW50c19hY3RpZnMrKzsKICAgICAgICBjb21wdGV1cl9jbGllbnRzKys7CiAgICAgICAgbnVtZXJvX25vdXZlYXVfY2xpZW50ID0gY29tcHRldXJfY2xpZW50czsKICAgICAgICAKICAgICAgICBwcmludGYoIltTRVJWRVVSXSArKysgQ2xpZW50ICMlZCBjb25uZWN0ZSAoQWN0aWZzOiAlZCkgKysrXG4iLCAKICAgICAgICAgICAgICAgbnVtZXJvX25vdXZlYXVfY2xpZW50LCBjbGllbnRzX2FjdGlmcyk7CiAgICAgICAgCiAgICAgICAgewogICAgICAgICAgICBwaWRfdCBwaWQgPSBmb3JrKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAocGlkID09IDApIHsKICAgICAgICAgICAgICAgIC8qIFByb2Nlc3N1cyBmaWxzICovCiAgICAgICAgICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICAgICAgICAgIHRyYWl0ZXJfY2xpZW50KGNsaWVudF9mZCwgYWRyZXNzZV9jbGllbnQsIG51bWVyb19ub3V2ZWF1X2NsaWVudCk7CiAgICAgICAgICAgICAgICBleGl0KDApOwogICAgICAgICAgICB9IGVsc2UgaWYgKHBpZCA+IDApIHsKICAgICAgICAgICAgICAgIC8qIFByb2Nlc3N1cyBww6hyZSAqLwogICAgICAgICAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBlcnJvcigiZm9yayIpOwogICAgICAgICAgICAgICAgY2xpZW50c19hY3RpZnMtLTsKICAgICAgICAgICAgICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgcmV0dXJuIDA7Cn08L3ByZT53E2VubGlnaHRlci9jb2RlYmxvY2t3ij0jaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8c3lzL3dhaXQuaD4KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpbmNsdWRlIDx0aW1lLmg+CgojZGVmaW5lIFBPUlQgODA4MAojZGVmaW5lIEJVRkZFUl9TSVpFIDQwOTYKI2RlZmluZSBNQVhfQ0xJRU5UUyAxMDAKCmludCBjbGllbnRzX2FjdGlmcyA9IDA7CmludCBjb21wdGV1cl9jbGllbnRzID0gMDsKCnZvaWQgZ2VzdGlvbm5haXJlX3NpZ2NobGQoaW50IHNpZ25vKSB7CiAgICB3aGlsZSAod2FpdHBpZCgtMSwgTlVMTCwgV05PSEFORykgPiAwKSB7CiAgICAgICAgY2xpZW50c19hY3RpZnMtLTsKICAgIH0KfQoKLyogRW52b3llciB1bmUgcsOpcG9uc2UgSFRUUCAqLwp2b2lkIGVudm95ZXJfcmVwb25zZV9odHRwKGludCBjbGllbnRfZmQsIGNvbnN0IGNoYXIgKmJvZHkpIHsKICAgIGNoYXIgcmVwb25zZVtCVUZGRVJfU0laRV07CiAgICAKICAgIHNwcmludGYocmVwb25zZSwKICAgICAgICAgICAgIkhUVFAvMS4xIDIwMCBPS1xyXG4iCiAgICAgICAgICAgICJDb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1VVEYtOFxyXG4iCiAgICAgICAgICAgICJDb250ZW50LUxlbmd0aDogJWxkXHJcbiIKICAgICAgICAgICAgIkNvbm5lY3Rpb246IGNsb3NlXHJcbiIKICAgICAgICAgICAgIlNlcnZlcjogQU5TSS1DLzEuMFxyXG4iCiAgICAgICAgICAgICJcclxuIgogICAgICAgICAgICAiJXMiLAogICAgICAgICAgICBzdHJsZW4oYm9keSksIGJvZHkpOwogICAgCiAgICBzZW5kKGNsaWVudF9mZCwgcmVwb25zZSwgc3RybGVuKHJlcG9uc2UpLCAwKTsKfQoKLyogUGFnZSBkJ2FjY3VlaWwgKi8Kdm9pZCBlbnZveWVyX2FjY3VlaWwoaW50IGNsaWVudF9mZCwgaW50IG51bWVyb19jbGllbnQpIHsKICAgIGNoYXIgYm9keVtCVUZGRVJfU0laRV07CiAgICB0aW1lX3Qgbm93OwogICAgY2hhciBkYXRlX3N0cls2NF07CiAgICAKICAgIHRpbWUoJm5vdyk7CiAgICBzdHJmdGltZShkYXRlX3N0ciwgc2l6ZW9mKGRhdGVfc3RyKSwgIiVkLyVtLyVZICVIOiVNOiVTIiwgbG9jYWx0aW1lKCZub3cpKTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiPGh0bWw+XG4iCiAgICAgICAgICAgICI8aGVhZD5cbiIKICAgICAgICAgICAgIjx0aXRsZT5TZXJ2ZXVyIEFOU0kgQzwvdGl0bGU+XG4iCiAgICAgICAgICAgICI8L2hlYWQ+XG4iCiAgICAgICAgICAgICI8Ym9keT5cbiIKICAgICAgICAgICAgIjxoMT5TZXJ2ZXVyIEFOU0kgQzwvaDE+XG4iCiAgICAgICAgICAgICI8aHI+XG4iCiAgICAgICAgICAgICI8aDI+Q2xpZW50IG51bWVybyA6ICMlZDwvaDI+XG4iCiAgICAgICAgICAgICI8cD5DbGllbnRzIGFjdGlmcyA6ICVkPC9wPlxuIgogICAgICAgICAgICAiPHA+VG90YWwgY2xpZW50cyBzZXJ2aXMgOiAlZDwvcD5cbiIKICAgICAgICAgICAgIjxwPkRhdGUvSGV1cmUgOiAlczwvcD5cbiIKICAgICAgICAgICAgIjxwPlBvcnQgOiAlZCB8IFBJRCA6ICVkPC9wPlxuIgogICAgICAgICAgICAiPGhyPlxuIgogICAgICAgICAgICAiPHA+PGEgaHJlZj0nL3N0YXRzJz5Wb2lyIGxlcyBzdGF0aXN0aXF1ZXM8L2E+PC9wPlxuIgogICAgICAgICAgICAiPHA+PGEgaHJlZj0nL3F1aXQnPlF1aXR0ZXI8L2E+PC9wPlxuIgogICAgICAgICAgICAiPC9ib2R5PlxuIgogICAgICAgICAgICAiPC9odG1sPlxuIiwKICAgICAgICAgICAgbnVtZXJvX2NsaWVudCwgY2xpZW50c19hY3RpZnMsIGNvbXB0ZXVyX2NsaWVudHMsIGRhdGVfc3RyLCBQT1JULCBnZXRwaWQoKSk7CiAgICAKICAgIGVudm95ZXJfcmVwb25zZV9odHRwKGNsaWVudF9mZCwgYm9keSk7Cn0KCi8qIFBhZ2Ugc3RhdGlzdGlxdWVzICovCnZvaWQgZW52b3llcl9zdGF0cyhpbnQgY2xpZW50X2ZkLCBpbnQgbnVtZXJvX2NsaWVudCkgewogICAgY2hhciBib2R5W0JVRkZFUl9TSVpFXTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiPGh0bWw+XG4iCiAgICAgICAgICAgICI8aGVhZD5cbiIKICAgICAgICAgICAgIjx0aXRsZT5TdGF0aXN0aXF1ZXM8L3RpdGxlPlxuIgogICAgICAgICAgICAiPC9oZWFkPlxuIgogICAgICAgICAgICAiPGJvZHk+XG4iCiAgICAgICAgICAgICI8aDE+U3RhdGlzdGlxdWVzPC9oMT5cbiIKICAgICAgICAgICAgIjxocj5cbiIKICAgICAgICAgICAgIjxoMj5Wb3RyZSBudW1lcm8gOiAjJWQ8L2gyPlxuIgogICAgICAgICAgICAiPHA+Q2xpZW50cyBhY3R1ZWxsZW1lbnQgY29ubmVjdGVzIDogJWQ8L3A+XG4iCiAgICAgICAgICAgICI8cD5Ub3RhbCBjbGllbnRzIHNlcnZpcyBkZXB1aXMgZGVtYXJyYWdlIDogJWQ8L3A+XG4iCiAgICAgICAgICAgICI8cD5DYXBhY2l0ZSBtYXhpbWFsZSA6ICVkIGNsaWVudHM8L3A+XG4iCiAgICAgICAgICAgICI8aHI+XG4iCiAgICAgICAgICAgICI8cD48YSBocmVmPScvJz5SZXRvdXIgYWNjdWVpbDwvYT48L3A+XG4iCiAgICAgICAgICAgICI8L2JvZHk+XG4iCiAgICAgICAgICAgICI8L2h0bWw+XG4iLAogICAgICAgICAgICBudW1lcm9fY2xpZW50LCBjbGllbnRzX2FjdGlmcywgY29tcHRldXJfY2xpZW50cywgTUFYX0NMSUVOVFMpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBQYWdlIDQwNCAqLwp2b2lkIGVudm95ZXJfNDA0KGludCBjbGllbnRfZmQpIHsKICAgIGNoYXIgYm9keVtCVUZGRVJfU0laRV07CiAgICAKICAgIHNwcmludGYoYm9keSwKICAgICAgICAgICAgIjxodG1sPlxuIgogICAgICAgICAgICAiPGhlYWQ+XG4iCiAgICAgICAgICAgICI8dGl0bGU+NDA0PC90aXRsZT5cbiIKICAgICAgICAgICAgIjwvaGVhZD5cbiIKICAgICAgICAgICAgIjxib2R5PlxuIgogICAgICAgICAgICAiPGgxPjQwNCAtIFBhZ2Ugbm9uIHRyb3V2ZWU8L2gxPlxuIgogICAgICAgICAgICAiPGhyPlxuIgogICAgICAgICAgICAiPHA+TGEgcGFnZSBkZW1hbmRlZSBuJ2V4aXN0ZSBwYXMuPC9wPlxuIgogICAgICAgICAgICAiPHA+PGEgaHJlZj0nLyc+UmV0b3VyIGFjY3VlaWw8L2E+PC9wPlxuIgogICAgICAgICAgICAiPC9ib2R5PlxuIgogICAgICAgICAgICAiPC9odG1sPlxuIik7CiAgICAKICAgIGVudm95ZXJfcmVwb25zZV9odHRwKGNsaWVudF9mZCwgYm9keSk7Cn0KCi8qIFBhZ2UgYXUgcmV2b2lyICovCnZvaWQgZW52b3llcl9hdV9yZXZvaXIoaW50IGNsaWVudF9mZCkgewogICAgY2hhciBib2R5W0JVRkZFUl9TSVpFXTsKICAgIAogICAgc3ByaW50Zihib2R5LAogICAgICAgICAgICAiPGh0bWw+XG4iCiAgICAgICAgICAgICI8aGVhZD5cbiIKICAgICAgICAgICAgIjx0aXRsZT5BdSByZXZvaXI8L3RpdGxlPlxuIgogICAgICAgICAgICAiPC9oZWFkPlxuIgogICAgICAgICAgICAiPGJvZHk+XG4iCiAgICAgICAgICAgICI8aDE+QXUgcmV2b2lyICE8L2gxPlxuIgogICAgICAgICAgICAiPGhyPlxuIgogICAgICAgICAgICAiPHA+TWVyY2kgZCdhdm9pciB2aXNpdGUgbm90cmUgc2VydmV1ciBBTlNJIEMuPC9wPlxuIgogICAgICAgICAgICAiPHA+PGEgaHJlZj0nLyc+Tm91dmVsbGUgY29ubmV4aW9uPC9hPjwvcD5cbiIKICAgICAgICAgICAgIjwvYm9keT5cbiIKICAgICAgICAgICAgIjwvaHRtbD5cbiIpOwogICAgCiAgICBlbnZveWVyX3JlcG9uc2VfaHR0cChjbGllbnRfZmQsIGJvZHkpOwp9CgovKiBFeHRyYWlyZSBsZSBjaGVtaW4gZGUgbGEgcmVxdcOqdGUgSFRUUCAqLwp2b2lkIGV4dHJhaXJlX2NoZW1pbihjb25zdCBjaGFyICpyZXF1ZXRlLCBjaGFyICpjaGVtaW4pIHsKICAgIGNoYXIgbWV0aG9kWzE2XTsKICAgIGNoYXIgcGF0aFsyNTZdOwogICAgY2hhciB2ZXJzaW9uWzE2XTsKICAgIAogICAgc3NjYW5mKHJlcXVldGUsICIlcyAlcyAlcyIsIG1ldGhvZCwgcGF0aCwgdmVyc2lvbik7CiAgICBzdHJjcHkoY2hlbWluLCBwYXRoKTsKfQoKdm9pZCB0cmFpdGVyX2NsaWVudChpbnQgY2xpZW50X2ZkLCBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRyZXNzZV9jbGllbnQsIGludCBudW1lcm9fY2xpZW50KSB7CiAgICBjaGFyIGJ1ZmZlcltCVUZGRVJfU0laRV07CiAgICBpbnQgYnl0ZXNfbHVzOwogICAgY2hhciBjaGVtaW5bMjU2XTsKICAgIGNoYXIgY2xpZW50X2lwW0lORVRfQUREUlNUUkxFTl07CiAgICAKICAgIGluZXRfbnRvcChBRl9JTkVULCAmYWRyZXNzZV9jbGllbnQuc2luX2FkZHIsIGNsaWVudF9pcCwgSU5FVF9BRERSU1RSTEVOKTsKICAgIAogICAgcHJpbnRmKCJbQ2xpZW50ICMlZF0gQ29ubmVjdGUgZGVwdWlzICVzOiVkXG4iLCAKICAgICAgICAgICBudW1lcm9fY2xpZW50LCBjbGllbnRfaXAsIG50b2hzKGFkcmVzc2VfY2xpZW50LnNpbl9wb3J0KSk7CiAgICAKICAgIC8qIExpcmUgbGEgcmVxdcOqdGUgKi8KICAgIGJ5dGVzX2x1cyA9IHJlY3YoY2xpZW50X2ZkLCBidWZmZXIsIEJVRkZFUl9TSVpFIC0gMSwgMCk7CiAgICBpZiAoYnl0ZXNfbHVzIDw9IDApIHsKICAgICAgICBjbG9zZShjbGllbnRfZmQpOwogICAgICAgIGV4aXQoMCk7CiAgICB9CiAgICAKICAgIGJ1ZmZlcltieXRlc19sdXNdID0gJ1wwJzsKICAgIGV4dHJhaXJlX2NoZW1pbihidWZmZXIsIGNoZW1pbik7CiAgICAKICAgIHByaW50ZigiW0NsaWVudCAjJWRdIENoZW1pbjogJXNcbiIsIG51bWVyb19jbGllbnQsIGNoZW1pbik7CiAgICAKICAgIC8qIFJvdXRlciBzZWxvbiBsZSBjaGVtaW4gKi8KICAgIGlmIChzdHJjbXAoY2hlbWluLCAiLyIpID09IDAgfHwgc3RyY21wKGNoZW1pbiwgIi9pbmRleC5odG1sIikgPT0gMCkgewogICAgICAgIGVudm95ZXJfYWNjdWVpbChjbGllbnRfZmQsIG51bWVyb19jbGllbnQpOwogICAgfQogICAgZWxzZSBpZiAoc3RyY21wKGNoZW1pbiwgIi9zdGF0cyIpID09IDApIHsKICAgICAgICBlbnZveWVyX3N0YXRzKGNsaWVudF9mZCwgbnVtZXJvX2NsaWVudCk7CiAgICB9CiAgICBlbHNlIGlmIChzdHJjbXAoY2hlbWluLCAiL3F1aXQiKSA9PSAwKSB7CiAgICAgICAgZW52b3llcl9hdV9yZXZvaXIoY2xpZW50X2ZkKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGVudm95ZXJfNDA0KGNsaWVudF9mZCk7CiAgICB9CiAgICAKICAgIHByaW50ZigiW0NsaWVudCAjJWRdIERlY29ubmV4aW9uXG4iLCBudW1lcm9fY2xpZW50KTsKICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICBleGl0KDApOwp9CgppbnQgbWFpbih2b2lkKSB7CiAgICBpbnQgc2VydmV1cl9mZCwgY2xpZW50X2ZkOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkcmVzc2Vfc2VydmV1ciwgYWRyZXNzZV9jbGllbnQ7CiAgICBzb2NrbGVuX3QgdGFpbGxlX2NsaWVudCA9IHNpemVvZihhZHJlc3NlX2NsaWVudCk7CiAgICBpbnQgb3B0ID0gMTsKICAgIGludCBudW1lcm9fbm91dmVhdV9jbGllbnQ7CiAgICAKICAgIC8qIEdlc3Rpb24gZGVzIHNpZ25hdXggKi8KICAgIHNpZ25hbChTSUdDSExELCBnZXN0aW9ubmFpcmVfc2lnY2hsZCk7CiAgICAKICAgIC8qIENyw6lhdGlvbiBzb2NrZXQgKi8KICAgIHNlcnZldXJfZmQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApOwogICAgaWYgKHNlcnZldXJfZmQgPCAwKSB7CiAgICAgICAgcGVycm9yKCJzb2NrZXQiKTsKICAgICAgICBleGl0KEVYSVRfRkFJTFVSRSk7CiAgICB9CiAgICAKICAgIC8qIE9wdGlvbiByZXVzZSBhZGRyZXNzICovCiAgICBzZXRzb2Nrb3B0KHNlcnZldXJfZmQsIFNPTF9TT0NLRVQsIFNPX1JFVVNFQUREUiwgJm9wdCwgc2l6ZW9mKG9wdCkpOwogICAgCiAgICAvKiBDb25maWd1cmF0aW9uIGFkcmVzc2UgKi8KICAgIG1lbXNldCgmYWRyZXNzZV9zZXJ2ZXVyLCAwLCBzaXplb2YoYWRyZXNzZV9zZXJ2ZXVyKSk7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBhZHJlc3NlX3NlcnZldXIuc2luX2FkZHIuc19hZGRyID0gSU5BRERSX0FOWTsKICAgIGFkcmVzc2Vfc2VydmV1ci5zaW5fcG9ydCA9IGh0b25zKFBPUlQpOwogICAgCiAgICAvKiBCaW5kICovCiAgICBpZiAoYmluZChzZXJ2ZXVyX2ZkLCAoc3RydWN0IHNvY2thZGRyICopJmFkcmVzc2Vfc2VydmV1ciwgc2l6ZW9mKGFkcmVzc2Vfc2VydmV1cikpIDwgMCkgewogICAgICAgIHBlcnJvcigiYmluZCIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgLyogTGlzdGVuICovCiAgICBpZiAobGlzdGVuKHNlcnZldXJfZmQsIE1BWF9DTElFTlRTKSA8IDApIHsKICAgICAgICBwZXJyb3IoImxpc3RlbiIpOwogICAgICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIH0KICAgIAogICAgcHJpbnRmKCJcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOwogICAgcHJpbnRmKCJTRVJWRVVSIEhUVFAgQU5TSSBDXG4iKTsKICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CiAgICBwcmludGYoIlBvcnQ6ICVkXG4iLCBQT1JUKTsKICAgIHByaW50ZigiVVJMOiBodHRwOi8vbG9jYWxob3N0OiVkL1xuIiwgUE9SVCk7CiAgICBwcmludGYoIlBJRDogJWRcbiIsIGdldHBpZCgpKTsKICAgIHByaW50ZigiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4iKTsKICAgIAogICAgLyogQm91Y2xlIHByaW5jaXBhbGUgKi8KICAgIHdoaWxlICgxKSB7CiAgICAgICAgY2xpZW50X2ZkID0gYWNjZXB0KHNlcnZldXJfZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikmYWRyZXNzZV9jbGllbnQsICZ0YWlsbGVfY2xpZW50KTsKICAgICAgICBpZiAoY2xpZW50X2ZkIDwgMCkgewogICAgICAgICAgICBwZXJyb3IoImFjY2VwdCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgY2xpZW50c19hY3RpZnMrKzsKICAgICAgICBjb21wdGV1cl9jbGllbnRzKys7CiAgICAgICAgbnVtZXJvX25vdXZlYXVfY2xpZW50ID0gY29tcHRldXJfY2xpZW50czsKICAgICAgICAKICAgICAgICBwcmludGYoIltTRVJWRVVSXSArKysgQ2xpZW50ICMlZCBjb25uZWN0ZSAoQWN0aWZzOiAlZCkgKysrXG4iLCAKICAgICAgICAgICAgICAgbnVtZXJvX25vdXZlYXVfY2xpZW50LCBjbGllbnRzX2FjdGlmcyk7CiAgICAgICAgCiAgICAgICAgewogICAgICAgICAgICBwaWRfdCBwaWQgPSBmb3JrKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAocGlkID09IDApIHsKICAgICAgICAgICAgICAgIC8qIFByb2Nlc3N1cyBmaWxzICovCiAgICAgICAgICAgICAgICBjbG9zZShzZXJ2ZXVyX2ZkKTsKICAgICAgICAgICAgICAgIHRyYWl0ZXJfY2xpZW50KGNsaWVudF9mZCwgYWRyZXNzZV9jbGllbnQsIG51bWVyb19ub3V2ZWF1X2NsaWVudCk7CiAgICAgICAgICAgICAgICBleGl0KDApOwogICAgICAgICAgICB9IGVsc2UgaWYgKHBpZCA+IDApIHsKICAgICAgICAgICAgICAgIC8qIFByb2Nlc3N1cyBww6hyZSAqLwogICAgICAgICAgICAgICAgY2xvc2UoY2xpZW50X2ZkKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBlcnJvcigiZm9yayIpOwogICAgICAgICAgICAgICAgY2xpZW50c19hY3RpZnMtLTsKICAgICAgICAgICAgICAgIGNsb3NlKGNsaWVudF9mZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIGNsb3NlKHNlcnZldXJfZmQpOwogICAgcmV0dXJuIDA7Cn13AWN3AHcAdwB3AHcAdwB5eXl5eXUAeXcAfZAGfQB3BGVhc2V5dwB3A3RvcHl9AHtCedjHxfcQAHtB4v96OkAAAAHSo++\/CQELAA==\",\"updateId\":414650378}","_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-7568","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Socket TCP en C ansi - workboot<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Socket TCP en C ansi - workboot\" \/>\n<meta property=\"og:description\" content=\"Serveur TCP Makefile Client TCP Makefile Muti_serveur (fork) Serveur http Serveur http multi-client\" \/>\n<meta property=\"og:url\" content=\"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/\" \/>\n<meta property=\"og:site_name\" content=\"workboot\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-14T14:54:27+00:00\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/sockets-en-c-ansi\\\/\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/sockets-en-c-ansi\\\/\",\"name\":\"Socket TCP en C ansi - workboot\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#website\"},\"datePublished\":\"2026-04-03T06:49:32+00:00\",\"dateModified\":\"2026-04-14T14:54:27+00:00\",\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/workboot.fr\\\/ciela\\\/sockets-en-c-ansi\\\/\"]}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#website\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/\",\"name\":\"workboot\",\"description\":\"Open Source, Open Minds \",\"publisher\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#organization\",\"name\":\"workboot\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/logo_ciel-dorian-1.png\",\"contentUrl\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/logo_ciel-dorian-1.png\",\"width\":1024,\"height\":950,\"caption\":\"workboot\"},\"image\":{\"@id\":\"https:\\\/\\\/workboot.fr\\\/ciela\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Socket TCP en C ansi - workboot","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/","og_locale":"fr_FR","og_type":"article","og_title":"Socket TCP en C ansi - workboot","og_description":"Serveur TCP Makefile Client TCP Makefile Muti_serveur (fork) Serveur http Serveur http multi-client","og_url":"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/","og_site_name":"workboot","article_modified_time":"2026-04-14T14:54:27+00:00","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/","url":"https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/","name":"Socket TCP en C ansi - workboot","isPartOf":{"@id":"https:\/\/workboot.fr\/ciela\/#website"},"datePublished":"2026-04-03T06:49:32+00:00","dateModified":"2026-04-14T14:54:27+00:00","inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/workboot.fr\/ciela\/sockets-en-c-ansi\/"]}]},{"@type":"WebSite","@id":"https:\/\/workboot.fr\/ciela\/#website","url":"https:\/\/workboot.fr\/ciela\/","name":"workboot","description":"Open Source, Open Minds ","publisher":{"@id":"https:\/\/workboot.fr\/ciela\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/workboot.fr\/ciela\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/workboot.fr\/ciela\/#organization","name":"workboot","url":"https:\/\/workboot.fr\/ciela\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/workboot.fr\/ciela\/#\/schema\/logo\/image\/","url":"https:\/\/workboot.fr\/ciela\/wp-content\/uploads\/2025\/05\/logo_ciel-dorian-1.png","contentUrl":"https:\/\/workboot.fr\/ciela\/wp-content\/uploads\/2025\/05\/logo_ciel-dorian-1.png","width":1024,"height":950,"caption":"workboot"},"image":{"@id":"https:\/\/workboot.fr\/ciela\/#\/schema\/logo\/image\/"}}]}},"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"https:\/\/workboot.fr\/ciela\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"Serveur TCP Makefile Client TCP Makefile Muti_serveur (fork) Serveur http Serveur http multi-client","_links":{"self":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/7568","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/comments?post=7568"}],"version-history":[{"count":16,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/7568\/revisions"}],"predecessor-version":[{"id":7710,"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/pages\/7568\/revisions\/7710"}],"wp:attachment":[{"href":"https:\/\/workboot.fr\/ciela\/wp-json\/wp\/v2\/media?parent=7568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}