\hypertarget{ecore_fd_handler_gnutls_example_8c-example}{\section{ecore\+\_\+fd\+\_\+handler\+\_\+gnutls\+\_\+example.\+c}
}
Shows how to use fd handlers.


\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{// gcc -o ecore\_fd\_handler\_gnutls\_example ecore\_fd\_handler\_gnutls\_example.c `pkg-config --cflags --libs
       ecore gnutls`}

\textcolor{preprocessor}{#include <Ecore.h>}
\textcolor{preprocessor}{#include <fcntl.h>}
\textcolor{preprocessor}{#include <netinet/tcp.h>}
\textcolor{preprocessor}{#include <netinet/in.h>}
\textcolor{preprocessor}{#include <sys/socket.h>}
\textcolor{preprocessor}{#include <arpa/inet.h>}
\textcolor{preprocessor}{#include <errno.h>}
\textcolor{preprocessor}{#include <unistd.h>}
\textcolor{preprocessor}{#include <gnutls/gnutls.h>}

\textcolor{comment}{/* Ecore\_Fd\_Handler example}
\textcolor{comment}{ * 2010 Mike Blumenkrantz}
\textcolor{comment}{ * compile with gcc $(pkgconfig --cflags --libs gnutls ecore)}
\textcolor{comment}{ */}

\textcolor{preprocessor}{#define print(...) fprintf(stderr, "line %i: ", \_\_LINE\_\_); fprintf(stderr, \_\_VA\_ARGS\_\_); fprintf(stderr, "\(\backslash\)
      n")}

\textcolor{keyword}{static} \textcolor{keywordtype}{int} done = 0;

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
tls\_log\_func(\textcolor{keywordtype}{int} level, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str)
\{
   fprintf(stderr, \textcolor{stringliteral}{"|<%d>| %s"}, level, str);
\}

\textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{char} *
SSL\_GNUTLS\_PRINT\_HANDSHAKE\_STATUS(gnutls\_handshake\_description\_t status)
\{
   \textcolor{keywordflow}{switch} (status)
     \{
      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_HELLO\_REQUEST:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Hello request"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_CLIENT\_HELLO:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Client hello"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_SERVER\_HELLO:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Server hello"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_CERTIFICATE\_PKT:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Certificate packet"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_SERVER\_KEY\_EXCHANGE:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Server key exchange"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_CERTIFICATE\_REQUEST:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Certificate request"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_SERVER\_HELLO\_DONE:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Server hello done"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_CERTIFICATE\_VERIFY:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Certificate verify"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_CLIENT\_KEY\_EXCHANGE:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Client key exchange"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_FINISHED:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Finished"};

      \textcolor{keywordflow}{case} GNUTLS\_HANDSHAKE\_SUPPLEMENTAL:
        \textcolor{keywordflow}{return} \textcolor{stringliteral}{"Supplemental"};
     \}
   \textcolor{keywordflow}{return} NULL;
\}

\textcolor{comment}{/* Connects to the peer and returns a socket}
\textcolor{comment}{ * descriptor.}
\textcolor{comment}{ */}
\textcolor{keyword}{static} \textcolor{keywordtype}{int}
tcp\_connect(\textcolor{keywordtype}{void})
\{
   \textcolor{keyword}{const} \textcolor{keywordtype}{char} *PORT = \textcolor{stringliteral}{"443"};
   \textcolor{keyword}{const} \textcolor{keywordtype}{char} *SERVER = \textcolor{stringliteral}{"69.58.181.89"}; \textcolor{comment}{//verisign.com}
   \textcolor{keywordtype}{int} err, sd;
   \textcolor{keywordtype}{int} flag = 1, curstate = 0;
   \textcolor{keyword}{struct }sockaddr\_in sa;

   \textcolor{comment}{/* sets some fd options such as nonblock */}
   sd = socket(AF\_INET, SOCK\_STREAM, 0);
   \hyperlink{group__Evil_gad39ebe4c4767eaa9a680777400cfaafe}{fcntl}(sd, F\_SETFL, O\_NONBLOCK);
   \hyperlink{group__Evil_gad39ebe4c4767eaa9a680777400cfaafe}{fcntl}(sd, F\_SETFD, FD\_CLOEXEC);
   setsockopt(sd, SOL\_SOCKET, SO\_REUSEADDR, (\textcolor{keyword}{const} \textcolor{keywordtype}{void} *)&curstate, \textcolor{keyword}{sizeof}(curstate));

   setsockopt(sd, IPPROTO\_TCP, TCP\_NODELAY, (\textcolor{keywordtype}{char} *)&flag, \textcolor{keyword}{sizeof}(\textcolor{keywordtype}{int}));

   memset(&sa, \textcolor{charliteral}{'\(\backslash\)0'}, \textcolor{keyword}{sizeof} (sa));
   sa.sin\_family = AF\_INET;
   sa.sin\_port = htons(atoi(PORT));
   \hyperlink{group__Evil__Inet__Group_ga2e4ab3dd91a2f3f88e514beeb7dd474f}{inet\_pton}(AF\_INET, SERVER, &sa.sin\_addr);

   \textcolor{comment}{/* connects to server}
\textcolor{comment}{    */}
   err = connect(sd, (\textcolor{keyword}{struct} sockaddr *)&sa, \textcolor{keyword}{sizeof} (sa));
   \textcolor{keywordflow}{if} ((err < 0) && (errno != EINPROGRESS))
     \{
        print(\textcolor{stringliteral}{"Connect error\(\backslash\)n"});
        exit(1);
     \}

   \textcolor{keywordflow}{return} sd;
\}

\textcolor{comment}{/* closes the given socket descriptor.}
\textcolor{comment}{ */}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
tcp\_close(\textcolor{keywordtype}{int} sd)
\{
   shutdown(sd, SHUT\_RDWR);     \textcolor{comment}{/* no more receptions */}
   close(sd);
\}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_process\_data(gnutls\_session\_t client, \hyperlink{group__Ecore__FD__Handler__Group_ga225121ed2123da4b52b76aa08d78c220}{Ecore\_Fd\_Handler} *fd\_handler)
\{
   \textcolor{keyword}{static} \textcolor{keywordtype}{int} ret, lastret;
   \textcolor{keyword}{static} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} count = 0;

   \textcolor{keywordflow}{if} (!done)
     \{
        lastret = ret;
        ret = gnutls\_handshake(client);
        count++;
        \textcolor{keywordflow}{if} (gnutls\_record\_get\_direction(client))
          \hyperlink{group__Ecore__FD__Handler__Group_gac7d30608fdd863ebde9a7870e2e7f1ff}{ecore\_main\_fd\_handler\_active\_set}(fd\_handler, 
      \hyperlink{group__Ecore__FD__Handler__Group_ggab5644f471dfa3bd182619601d9b60608a654f7e6af4875742c5349c2cc55d1bab}{ECORE\_FD\_WRITE});
        \textcolor{keywordflow}{else}
          \hyperlink{group__Ecore__FD__Handler__Group_gac7d30608fdd863ebde9a7870e2e7f1ff}{ecore\_main\_fd\_handler\_active\_set}(fd\_handler, 
      \hyperlink{group__Ecore__FD__Handler__Group_ggab5644f471dfa3bd182619601d9b60608a1699f804eccf88e7e169a4a20f1d44e7}{ECORE\_FD\_READ});
        \textcolor{comment}{/* avoid printing messages infinity times */}
        \textcolor{keywordflow}{if} (lastret != ret)
          \{
             print(\textcolor{stringliteral}{"gnutls returned with: %s - %s"}, gnutls\_strerror\_name(ret), gnutls\_strerror(ret));
             \textcolor{keywordflow}{if} ((ret == GNUTLS\_E\_WARNING\_ALERT\_RECEIVED) || (ret == GNUTLS\_E\_FATAL\_ALERT\_RECEIVED))
               print(\textcolor{stringliteral}{"Also received alert: %s"}, gnutls\_alert\_get\_name(gnutls\_alert\_get(client)));
             print(\textcolor{stringliteral}{"last out: %s"}, SSL\_GNUTLS\_PRINT\_HANDSHAKE\_STATUS(gnutls\_handshake\_get\_last\_out(client))
      );
             print(\textcolor{stringliteral}{"last in: %s"}, SSL\_GNUTLS\_PRINT\_HANDSHAKE\_STATUS(gnutls\_handshake\_get\_last\_in(client)));
          \}

        \textcolor{keywordflow}{if} (gnutls\_error\_is\_fatal(ret))
          \{
             print(\textcolor{stringliteral}{"yarrr this be an error!"});
             exit(1);
          \}
     \}
   \textcolor{keywordflow}{if} (ret == GNUTLS\_E\_SUCCESS)
     \{
        done = 1;
        print(\textcolor{stringliteral}{"Handshake successful in %u handshake calls!"}, count);
        \hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}();
     \}

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW};
\}

\textcolor{keywordtype}{int}
main(\textcolor{keywordtype}{void})
\{
   \textcolor{comment}{/* credentials */}
   gnutls\_anon\_client\_credentials\_t c\_anoncred;
   gnutls\_certificate\_credentials\_t c\_certcred;

   gnutls\_session\_t client;
   \textcolor{keywordtype}{int} sd;

   \textcolor{comment}{/* General init. */}
   gnutls\_global\_init();
   \hyperlink{group__Ecore__Init__Group_ga77757609684a2c922dc5ec398274751b}{ecore\_init}();
   gnutls\_global\_set\_log\_function(tls\_log\_func);
   gnutls\_global\_set\_log\_level(6);

   \textcolor{comment}{/* Init client */}
   gnutls\_anon\_allocate\_client\_credentials(&c\_anoncred);
   gnutls\_certificate\_allocate\_credentials(&c\_certcred);
   gnutls\_init(&client, GNUTLS\_CLIENT);
   \textcolor{comment}{/* set very specific priorities */}
   gnutls\_priority\_set\_direct(client, \textcolor{stringliteral}{"
      NONE:%VERIFY\_ALLOW\_X509\_V1\_CA\_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+CO
      MP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"}, NULL);
   gnutls\_credentials\_set(client, GNUTLS\_CRD\_ANON, c\_anoncred);
   gnutls\_credentials\_set(client, GNUTLS\_CRD\_CERTIFICATE, c\_certcred);
   gnutls\_server\_name\_set(client, GNUTLS\_NAME\_DNS, \textcolor{stringliteral}{"www.verisign.com"}, strlen(\textcolor{stringliteral}{"www.verisign.com"}));

   \textcolor{comment}{/* connect to the peer}
\textcolor{comment}{    */}
   sd = tcp\_connect();

   \textcolor{comment}{/* associate gnutls with socket */}
   gnutls\_transport\_set\_ptr(client, (gnutls\_transport\_ptr\_t)sd);
   \textcolor{comment}{/* add a callback for data being available for send/receive on socket */}
   \textcolor{keywordflow}{if} (!\hyperlink{group__Ecore__FD__Handler__Group_ga832e68eb7f15912abeadef816bb5d2f5}{ecore\_main\_fd\_handler\_add}(sd, \hyperlink{group__Ecore__FD__Handler__Group_ggab5644f471dfa3bd182619601d9b60608a1699f804eccf88e7e169a4a20f1d44e7}{ECORE\_FD\_READ} | 
      \hyperlink{group__Ecore__FD__Handler__Group_ggab5644f471dfa3bd182619601d9b60608a654f7e6af4875742c5349c2cc55d1bab}{ECORE\_FD\_WRITE}, (\hyperlink{group__Ecore__FD__Handler__Group_ga233a4c637db3fe2257c08ef64ca42b4a}{Ecore\_Fd\_Cb})\_process\_data, client, NULL, NULL))
     \{
        print(\textcolor{stringliteral}{"could not create fd handler!"});
        exit(1);
     \}
   \textcolor{comment}{/* begin main loop */}
   \hyperlink{group__Ecore__Main__Loop__Group_gaf103b9f668bb3e4fed12e52c6180132d}{ecore\_main\_loop\_begin}();

   gnutls\_bye(client, GNUTLS\_SHUT\_RDWR);

   gnutls\_deinit(client);

   tcp\_close(sd);

   \textcolor{keywordflow}{return} 0;
\}

\end{DoxyCodeInclude}
 