{"id":1799,"date":"2022-03-02T20:17:21","date_gmt":"2022-03-02T18:17:21","guid":{"rendered":"https:\/\/moijari.com\/?p=1799"},"modified":"2022-04-07T19:25:46","modified_gmt":"2022-04-07T17:25:46","slug":"dbs-0-12-finally-server-stays-up","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=1799","title":{"rendered":"DBS 0.12 Finally server stays up"},"content":{"rendered":"\n<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n. Maailman parhaat satunnaisbitit: <a href=\"https:\/\/moijari.com:5006\">https:\/\/moijari.com:5006<\/a>. \u00c4l\u00e4 kuitenkaan k\u00e4yt\u00e4 n\u00e4it\u00e4 sellaisenaan, summaa useampi generaattori, ja mielell\u00e4\u00e4n viimeinen omassa ohjelmassa.<\/p>\n\n\n\n<p>Edit korjailen raporttia l\u00e4hip\u00e4ivien ja viikkojen aikana. Sorsia en ole viel\u00e4 kokeillut k\u00e4\u00e4nt\u00e4\u00e4&#8230; Sain k\u00e4\u00e4nnetty\u00e4 sorsan. My\u00f6s html lokit kirjoitetaan useammassa osassa. Lis\u00e4tty palvelimiin vuorot lokien kirjoittamiseen. Raportti postin lopussa ennen sorsia. Korjattu pari bugia (uusi versio 0.14) ja lis\u00e4tty koodia aktiivisuuden laskentaan ja lis\u00e4tty yhteinen loki terttu hengess\u00e4 kaikille palvelimille. Lis\u00e4tty viel\u00e4 muutoksia newressu.c tiedostoon, kappaleita lis\u00e4tty loppuun ennen l\u00e4hdekoodia.<\/p>\n\n\n\n<p>Aiemmassa versiossa oli ongelmana se, ett\u00e4 jos asiakas ei toteuta protokollaa oikein, palvelin saattoi pys\u00e4hty\u00e4 ns blokkaavaan eli odottamaan j\u00e4\u00e4v\u00e4\u00e4n funktioon. T\u00e4m\u00e4n vuoksi uudet palvelimet (http ja https) luovat fork():lla lapsiprosessin, joka suorittaa toiminnot access() kutsusta l\u00e4htien. N\u00e4in jos lapsiprosessi &#8220;hyytyy&#8221; se ei hyydyt\u00e4 koko palvelinta. Seuraavana https palvelimen lapsiprosessi:<\/p>\n\n\n\n<p>Jos palvelimeen tulee useita p\u00e4\u00e4llekk\u00e4isi\u00e4 kyselyit\u00e4 ne periaatteessa suoritetaan uudessa versiossa samaan aikaan, ja lokiin tulostuvat useamman prosessin lokirivit sekoittuneina. T\u00e4t\u00e4 korjaamaan on lis\u00e4tty uusi log_printf, jossa yhden prosessin lokirivit ker\u00e4t\u00e4\u00e4n muistialueeseen ja t\u00e4m\u00e4 puskuri kirjoitetaan yhdell\u00e4 kertaa prosessin p\u00e4\u00e4ttyess\u00e4. N\u00e4in eri kutsujen lokirivit pysyv\u00e4t eroteltuina.<\/p>\n\n\n\n<p>Lis\u00e4ksi yhteiset osat https_client:ist\u00e4 ja http_clientist\u00e4 on yhdistetty dbs_server_vars() funktioon.<\/p>\n\n\n\n<p>SSL_read yritt\u00e4\u00e4 lukua uudelleen viisi kertaa (error 1 ja error 5). Uudelleen lukujen v\u00e4liss\u00e4 on kymmenesosasekunnin odotus (usleep()). <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)\n{\n  int status, ok;\n  unsigned char buffer10&#91;10];\n\n  SSL *ssl;\n  X509 *peer_cert;\n\n  ok=1;\n  \/\/ plus space for '\\0'  \n  htmlin = malloc(htmlinlen+1);\n\n  dbs_server_vars(sa_cli,addr_size,name);\n  \n  if((ssl=SSL_new(ctx)) == NULL) {\n    log_printf(\"\\n%s: cannot SSL_new()\", procname);\n  }\n  \n  if(SSL_set_fd(ssl,news) != 1) {\n    log_printf(\"\\n%s: cannot SSL_set_fd()\", procname);\n  }\n  \n  status=SSL_accept(ssl);\n  \n  peer_cert = SSL_get_peer_certificate(ssl);\n  if(peer_cert == NULL) {\n    log_printf(\", No peer certificate\");\n  }\n  \n  log_printf(\"\\n\");\n  \n  int clen = 0;\n  int reads = 0;\n  int first = 1;\n  htmlparams = NULL;\n  int bytes, totalbytes = 0;\n\n  htmlin&#91;0]='\\0';\n  while(htmlparams==NULL || clen-strlen(htmlparams) &gt; 0) {\n    if(!first) {\n      log_printf(\", \");\n    }\n#ifdef DEBUG68\n    log_printf(\"SSL_read\\n\");\n#endif\n    int tries=0;\n    for(;;) {\n      bytes = SSL_read(ssl, htmlin+totalbytes, htmlinlen-totalbytes);\n\n      int errerrno, err, err2;\n\n      errerrno=errno;\n      err=SSL_get_error(ssl,bytes);\n      err2=ERR_get_error();\n\n      log_printf(\"\\nSSL_read()\");\n      log_printf(\", retval %d\", bytes);\n      log_printf(\", errno: %d\", errerrno);\n      log_printf(\", SSL_get_error(): %d\", err);\n      log_printf(\", ERR_get_error(): %d\", err2);\n\n      while((err2=ERR_get_error())!=0)\n\tlog_printf(\", %d\",err2);\n      if(bytes&gt;=0) {\n\treads++;\n\tbreak;\n      }\n      if(bytes&lt;0) {\n\tif(++tries&lt;5 &amp;&amp; (err==1 || err==5)) {\n\t  log_printf(\" try:%d\",tries);\n\t  usleep(1024*512\/5);\n\t  continue;\n\t}\n\tlog_printf(\"\\n%s: cannot SSL_read()\", procname);\n\tok=0;\n\tbreak;\n      } \/\/ if(bytes\n      break;\n    } \/\/ for(;;)\n    log_printf(\"(%d bytes)\", bytes);\n    if(!ok)\n      break;\n\n    *(htmlin+totalbytes+bytes) = '\\0';\n    if(bytes==0)\n      break;\n\n    totalbytes+=bytes;\n    if(totalbytes &gt;= htmlinlen) {\n      \/\/ plus space for '\\0'\n      htmlin=realloc(htmlin, htmlinlen*2+1);\n      htmlinlen *= 2;\n    }\n    \n    htmlparams = dbs_html_get_params();\n    unsigned char *p=htmlin;\n    dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&amp;p);\n    if(!strcmp(htmlmethod,\"GET\"))\n      break;\n    dbs_html_get_request_line_num(\"Content-Length\",\n\t\t\t\t  sizeof(buffer10), buffer10);\n    clen = atoi(buffer10);\n    first = 0;\n  }\n  \n  log_printf(\"\\n%d reads\", reads);\n  log_printf(\", received %d chars\", totalbytes);\n  log_printf(\", read %d total bytes\", totalbytes);\n  log_printf(\", input buffer size %d chars\", htmlinlen);\n  log_printf(\", data=\\\"\");\n  log_dump_string(htmlin);\n  log_printf(\"\\\"\\n\");\n  \n  strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));\n  \n  if(ok) \n    dbs_run_loop();\n  \n  if(ok) {\n    log_printf(\"buffers(ssl):\");\n    for(int c=0;c&lt;HTML_BUFFERS;c++) {\n      log_printf(\" %d:%ld\",c,strlen(html_get_string(c)));\n      if(strlen(html_get_string(c))&gt;0) {\n#ifdef DEBUG68\n\tlog_printf(\"SSL_write\\n\");\n#endif\n\tif((status=SSL_write(ssl, html_get_string(c), strlen(html_get_string(c))))&lt;1) {\n\t  log_printf(\"\\n%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\",\n\t\t  procname, c, status, SSL_get_error(ssl,status));\n\t}\n      }\n    }\n  }\n  log_printf(\"\\n\");\n  log_printf(\"\\nSSL connection using %s\", htmlsslcipher);\n  log_printf(\"\\n\");\n \n#ifdef DEBUG68\n  log_printf(\"SSL_free\\n\");\n#endif\n  SSL_free(ssl);\n\n  free(htmlin);\n}<\/code><\/pre>\n\n\n\n<p>Edellinen tuottaa joillekin k\u00e4ytt\u00e4jille seuraavia virheit\u00e4, joita en ole viel\u00e4 saanut pois: Ne tosin voivat johtua my\u00f6s kutsujan protokollaongelmasta. Listassa on tietenkin viisi uudelleen yrityst\u00e4. Virheet tulevat vain joillekin k\u00e4ytt\u00e4jille, omissa testeiss\u00e4ni niit\u00e4 ei esiinny.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:1\nSSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:2\nSSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:3\nSSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:4\nSSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0\n.\/ressu4: cannot SSL_read()(-1 bytes)\n<\/code><\/pre>\n\n\n\n<p>Toisaalta SSL_write() tulostaa joskus t\u00e4ll\u00e4isen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/ressu4: cannot SSL_write(), buffer 0, status: -1, SSL error: 6\n.\/ressu4: cannot SSL_write(), buffer 8, status: -1, SSL error: 1, htmlparamslen: \"0\"<\/code><\/pre>\n\n\n\n<p>Seuraavassa varsinainen palvelinohjelma: se on samankaltainen kuin edellinenkin versio, t\u00e4h\u00e4n on lis\u00e4tty fork() kutsu, joka luo aina asiakkaan protokollaa varten uuden lapsiprosessin.<\/p>\n\n\n\n<p>Reset kytkint\u00e4 ei ole viel\u00e4 koodattu kokonaan, mutta ajatus on se ett\u00e4 palvelin huomaisi SSL avainmuutoksen ja palvelin ottaisi resetin avulla k\u00e4ytt\u00f6\u00f6n uudet avaimet.<\/p>\n\n\n\n<p>log_clear() kutsu tyhjent\u00e4\u00e4 lokin lapsiprosessin alussa (eli fork():in paluuarvolla 0). Kuten mainittu lapsiprosessissa lokiin kirjoitukset kirjoitetaan log_printf():ll\u00e4, siit\u00e4 lis\u00e4\u00e4 my\u00f6hemmin. log_free() vapauttaa lokin puskurialueen.<\/p>\n\n\n\n<p>Fork() suoritetaan yhden kerran, ja se palaa kahdesti, kerran lapsiprosessille paluuarvolla 0 ja kerran vanhempi prosessille, jolloin paluuarvo on lapsen prosessin id.<\/p>\n\n\n\n<p>Jos k\u00e4ynnist\u00e4t palvelimen $ nohup .\/ressu4 &#8211;port5006 &#8211;https &gt;&gt;ressu4.nohup &amp; -komennolla voit seurata palvelimen kutsuja  $ tail *.nohup -f -komennolla.<\/p>\n\n\n\n<p>https_server() kutsuu edellist\u00e4 asiakasfunktiota.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG59 2\n\nstatic void https_server()\n{\n  int quit, reset, addr_size;\n  \n  SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n\n  struct sockaddr_in sa_cli;\n  struct addrinfo *res;\n\n  signal(SIGPIPE, SIG_IGN);\n  signal(SIGCHLD, SIG_IGN);\n\n  reset=1;\n  quit=0;\n  \n  for(;;) {\n\n    if(quit) {\n      if(ctx!=NULL)\n\tSSL_CTX_free(ctx);\n      break;\n    }\n    if(reset) {\n      if(ctx!=NULL)\n\tSSL_CTX_free(ctx);  \n\n#ifdef DEBUG68\n      fprintf(stdout,\"SSL_library_init\\n\");\n      fflush(stdout);\n#endif\n\n      SSL_library_init();\n#ifdef DEBUG68\n      fprintf(stdout,\"OpenSSL_add_ssl_algorithms\\n\");\n      fflush(stdout);\n#endif\n      OpenSSL_add_ssl_algorithms();\n#ifdef DEBUG68\n      fprintf(stdout,\"OpenSSL_add_ciphers\\n\");\n      fflush(stdout);\n#endif\n      OpenSSL_add_all_ciphers();\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"OpenSSL_load_error_strings\\n\");\n      fflush(stdout);\n#endif\n      SSL_load_error_strings();\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"SSLv23_server_method\\n\");\n      fflush(stdout);\n#endif\n      if((method = (SSL_METHOD *)    \n\t  SSLv23_server_method()) == NULL) {\n\tfprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\n\tfflush(stderr);\n      }\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"SSL_CTX_new\\n\");\n      fflush(stdout);\n#endif\n      if((ctx=SSL_CTX_new(method)) == NULL) {\n\tfprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\n\tfflush(stderr);\n      }\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"SSL_CTX_use_certificate_file\\n\");\n      fflush(stdout);\n#endif\n      if(SSL_CTX_use_certificate_file(ctx,\n\t\t\t\t      cert_file, SSL_FILETYPE_PEM) &lt;= 0) {\n\tfprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\n\tfflush(stderr);\n      }\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"SSL_CTX_use_PrivateKey_file\\n\");\n      fflush(stdout);\n#endif\n      if(SSL_CTX_use_PrivateKey_file(ctx,\n\t\t\t\t     privatekey_file, SSL_FILETYPE_PEM)&lt;=0) {\n\tfprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\n\tfflush(stderr);\n      }\n      \n#ifdef DEBUG68\n      fprintf(stdout,\"SSL_CTX_load_verify_locations\\n\");\n      fflush(stdout);\n#endif\n      if(!SSL_CTX_load_verify_locations(ctx, \n\t\t\t\t\tcert_file, NULL)) {\n\tfprintf(stderr,\"\\n%s: cannot SSL_CTX_verify_locations()\", procname);\n\tfflush(stderr);\n      }\n      \n      server_getaddrinfo(myport, &amp;res);\n      s=server_socket(res);\n      server_bind(s, res);\n      freeaddrinfo(res);\n      server_listen(s);\n\n      reset=0;\n    } \/\/ if(reset)\n\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n    \n    addr_size = sizeof(sa_cli);\n#ifdef DEBUG68\n    fprintf(stdout,\"accept\\n\");\n    fflush(stdout);\n#endif\n    if((news=accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size))==-1) {\n      fprintf(stderr,\"\\n%s: cannot accept()\\n\", procname);\n      perror(\"accept\");\n      fflush(stderr);\n    }\n\n    if(beepaccept)\n      fprintf(stderr,\"\\a\");\n\n    pid_t pid;\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork start (parent)\");\n    fprintf(stdout,\" getpid:%d getppid:%d\\n\",getpid(),getppid()); \n    fflush(stdout);\n#endif\n    if((pid=fork())==0) {\n\n      log_clear();\n      log_printf(\"==========\");\n#ifdef DEBUG59\n      fprintf(stdout,\"Fork start (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\\n\",pid,getpid(),getppid());\n#endif\n      close(s);\n      https_client(news,ctx,sa_cli,addr_size,\"https\");\n      server_close(news);\n      fprintf(stdout,\"%s\",logbuf);\n#ifdef DEBUG59\n      fprintf(stdout,\"Fork end (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\\n\",pid,getpid(),getppid());\n      fflush(stdout);\n#endif\n      log_free();\n      exit(0);\n    }\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork end (parent)\");\n    fprintf(stdout,\" pid:%d getpid:%d getppid:%d\\n\",pid,getpid(),getppid());\n    fflush(stdout);\n#endif\n  } \/\/ for(;;)\n  SSL_CTX_free(ctx);  \n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa lokin tulostukseen tarkoitetut clear(), free, ja printf rutiinit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdarg.h&gt;\n\nunsigned char *logbuf=NULL;\nint logbuf_length=0;\n\nvoid log_clear()\n{\n  if(logbuf!=NULL)\n    logbuf&#91;0]='\\0';\n}\n\nvoid log_free()\n{\n  if(logbuf!=NULL) {\n    free(logbuf);\n    logbuf=NULL;\n  }\n}\n\nvoid log_printf(const char *format, ...)\n{\n  int count,size;\n  va_list args;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args,format);\n  count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf=realloc(printbuf, printbuf_len);\n    va_start(args,format);\n    count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n  if(logbuf==NULL ||\n     logbuf_length&lt;(size=(logbuf==NULL? 0:strlen(logbuf))+count)) {\n    unsigned char *temp=logbuf;\n    logbuf_length=size;\n    logbuf=realloc(logbuf,size);\n    if(temp==NULL)\n      logbuf&#91;0]='\\0';\n  }\n  strcat(logbuf,printbuf);\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavassa satunnaislukuohjelma joka on osoitteessa <a href=\"https:\/\/moijari.com:5006\">https:\/\/moijari.com:5006<\/a>. Tietenkin siell\u00e4 on my\u00f6s n\u00e4m\u00e4 muut postissa mainitut osuudet. Ja kuten aina lopussa on kopipastattavat sorsat.<\/p>\n\n\n\n<p>Ohjelma ajaa skriptin joka sis\u00e4lt\u00e4\u00e4 html rivej\u00e4 ja \/bin\/newressu komentoja. Jos scripti\u00e4 ei ole, sellainen luodaan. Scriptin luonnissa se kirjoitetaan tiedostoon ressu4script.html. Jos ajat palvelinta, muuta scripti haluamaksesi.<\/p>\n\n\n\n<p>Varsinaisessa palvelimessa scripti k\u00e4yd\u00e4\u00e4n rivi rivilt\u00e4 l\u00e4pi, ja suoritetaan &#8220;\/bin\/newressu &#8221; alkuiset rivit. Loput rivit tulostetaan sellaisenaan. Jos lis\u00e4\u00e4t palvelimeen komentoja, komennon nimi kannattaa varmaankin kovakoodata kuten t\u00e4ss\u00e4 &#8220;\/bin\/newressu&#8221;.<\/p>\n\n\n\n<p>Puolipisteell\u00e4 alkavat rivit ohitetaan kommentteina. Funktiolla popen() suoritetaan newressu-komento parametreineen ja saadaan fp2 tiedostohandle, josta voidaan lukea newressun tulostamat rivit.<\/p>\n\n\n\n<p>ressuoriginal.html sis\u00e4lt\u00e4\u00e4 html-scriptin joka tulostaa sivun lopun linkit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG8\n\nvoid ressu4_app()\n{\n  unsigned char *p;\n  unsigned char command&#91;128];\n  unsigned char buffer&#91;1024];\n  unsigned char script_file&#91;128]=\"ressu4script.html\";\n  FILE *fp1,*fp2;\n  \n  if((fp1=fopen(script_file,\"r\"))!=NULL) {\n    fclose(fp1);\n  } else {\n    if((fp1=fopen(script_file,\"w\"))!=NULL) {\n\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"; Script for ressu4 \u00a9\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h1&gt;%s&lt;\/h1&gt;\\n\",procheader);\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;p&gt;The next chapter consists of characters that\\n\");\n      fprintf(fp1,\" try to resemble throws of a 64 sided dice as closely as possible.\\n\");\n      fprintf(fp1,\" Characters have numbers from '0' to '9' (10 entries),\\n\");\n      fprintf(fp1,\" uppercase letters from 'A' to 'Z' (26 entries), lowercase letters\\n\");\n      fprintf(fp1,\" 'a' to 'z' (26 entries), '-' and '_' (2 entries).\\n\");\n      fprintf(fp1,\" Total is 10+26+26+2 = 64 values.\\n\");\n      fprintf(fp1,\" Characters are grouped into sets of 8 each. Throws\\n\");\n      fprintf(fp1,\" are random, so you cannot deduce value from\\n\");\n      fprintf(fp1,\" previous or next value(s).&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Newressu random numbers&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -2 -s8 -l1 -c5120 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -11 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random uppercase letters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -12 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random lowercase letters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -13 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Random characters in number systems&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random binary digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Following binary numbers are eight bits from 0 to 255 decimal.\\n\");\n      fprintf(fp1,\" From right to left the bit multipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal.\\n\");\n      fprintf(fp1,\" So 10000000b is 128d, 11111111b is 255d, 00000010b is 2d, 00000011b is 3d etc.\\n\");\n      fprintf(fp1,\" Here d after number means of course decimal. Digit numbers, b in 2^b, vary from 0 to 7.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -b -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random octal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;These octal numbers are also from 0 to 255 decimal (0 to 377 octal).\\n\");\n      fprintf(fp1,\" From right to left octal digit multipliers are 1, 8, 64 (8^o) in decimal.\\n\");\n      fprintf(fp1,\" Here 377o is 255d, 010o is 8d, 100o is 64d.\\n\");\n      fprintf(fp1,\" Each octal digit contains 3 binary bits, and 377o can be grouped\\n\");\n      fprintf(fp1,\" in binary like this 011 111 111.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -o --lim400 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random decimal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;These decimal numbers are from 0 to 99999. From right\\n\");\n      fprintf(fp1,\" to left decimal digit multipliers are 1, 10, 100, 1000 and 10000 (10^d).&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -d -s5 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random hexadecimal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Next hexadecimal numbers are from 0000h to ffffh meaning 0 to 65535 decimal.\\n\");\n      fprintf(fp1,\" Hexadecimal digit has numbers from 0 to 9 and letters a(10),\\n\");\n      fprintf(fp1,\" b(11), c(12), d(13), e(14) and f(15). From right to left hexadecimal multipliers\\n\");\n      fprintf(fp1,\" are 1, 16, 256, 4096 decimal (16^h). Each hexadecimal digit contains 4 bits so ffffh can be\\n\");\n      fprintf(fp1,\" grouped in binary like this 1111 1111 1111 1111.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -x -s4 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Random characters in languages&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;p&gt;The next chapters consists of random characters in various\\n\");\n      fprintf(fp1,\" languages. Most randomness is in chinese, japanese and\\n\");\n      fprintf(fp1,\" korean characters. Chinese has 20976 values per character,\\n\");\n      fprintf(fp1,\" japanese has 21158 values per character and korean has\\n\");\n      fprintf(fp1,\" 11172 values per character.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Latin (or roman) based alphabets have characters as follows:\\n\");\n      fprintf(fp1,\" danish alphabet has 58 characters,\\n\");\n      fprintf(fp1,\" deutsch alphabet has 60 characters,\\n\");\n      fprintf(fp1,\" english has 52 characters,\\n\");\n      fprintf(fp1,\" estonian has 64 characters,\\n\");\n      fprintf(fp1,\" finnish alphabet has 58 characters,\\n\");\n      fprintf(fp1,\" french character set has 52 characters,\\n\");\n      fprintf(fp1,\" italian character set has 52 characters,\\n\");\n      fprintf(fp1,\" latvian has 66 characters,\\n\");\n      fprintf(fp1,\" lithuanian has 64 characters,\\n\");\n      fprintf(fp1,\" norwegian has 58 characters,\\n\");\n      fprintf(fp1,\" swedish has 58 characters.\\n\");\n      fprintf(fp1,\" &lt;\/p&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Chinese random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --cn -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Danish random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\\n\");\n      fprintf(fp1,\"\/bin\/newressu --dnk -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Deutsch random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u1e9e\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00fc\u00df\\n\");\n      fprintf(fp1,\"\/bin\/newressu --deu -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;English random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --eng -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Estonian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRS\u0160Z\u017dTUVW\u00d5\u00c4\u00d6\u00dcXY\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrs\u0161z\u017etuvw\u00f5\u00e4\u00f6\u00fcxy\\n\");\n      fprintf(fp1,\"\/bin\/newressu --est -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Finnish random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\\n\");\n      fprintf(fp1,\"\/bin\/newressu --fin -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;French random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --fra -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Gothic random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --got -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Greek random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\\n\");\n      fprintf(fp1,\";\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\\n\");\n      fprintf(fp1,\"\/bin\/newressu --grc -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Italian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --ita -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Japanese random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --jp -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Korean random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --kor -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Latvian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";A\u0100BC\u010cDE\u0112FG\u0122HI\u012aJK\u0136L\u013bMN\u0145OPRS\u0160TU\u016aVZ\u017d\\n\");\n      fprintf(fp1,\";a\u0101bc\u010dde\u0113fg\u0123hi\u012bjk\u0137l\u013cmn\u0146oprs\u0161tu\u016bvz\u017e\\n\");\n      fprintf(fp1,\"\/bin\/newressu --lva -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Lithuanian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";A\u0104BC\u010cDE\u0118\u0116FGHI\u012eYJKLMNOPRS\u0160TU\u0172\u016aVZ\u017d\\n\");\n      fprintf(fp1,\";a\u0105bc\u010dde\u0119\u0117fghi\u012fyjklmnoprs\u0161tu\u0173\u016bvz\u017e\\n\");\n      fprintf(fp1,\"\/bin\/newressu --ltu -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Norwegian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\\n\");\n      fprintf(fp1,\"\/bin\/newressu --nor -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Russian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\\n\");\n      fprintf(fp1,\";\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\\n\");\n      fprintf(fp1,\"\/bin\/newressu --rus -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Swedish random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\\n\");\n      fprintf(fp1,\"\/bin\/newressu --swe -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Technical&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;This version runs newressu new for all of the previous\\n\");\n      fprintf(fp1,\" random number chapters (25 runs), so the buffer is empty in\\n\");\n      fprintf(fp1,\" the beginning of the chapter runs.\\n\");\n      fprintf(fp1,\" This whole page is created (including randomness) after your\\n\");\n      fprintf(fp1,\" network query is received,\\n\");\n      fprintf(fp1,\" so time newressu runs is quite reasonable.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;This version does random skips on clock material,\\n\");\n      fprintf(fp1,\" which makes it harder to guess it. Ressu skips\\n\");\n      fprintf(fp1,\" 0-255 bytes every ~1000 bytes.\\n\");\n      fprintf(fp1,\" This version also is ressu only, there is no whitening\\n\");\n      fprintf(fp1,\" or combining of other generators.&lt;\/p&gt;\\n\");\n      fclose(fp1);\n    }\n  } \/\/ if((fp1=fopen\n  if((fp1=fopen(script_file,\"r\"))!=NULL) {    \n    while(fgets(command,sizeof(command),fp1)!=NULL) {\n      if(command&#91;0]==';')\n\tcontinue;\n      else if(!strncmp(command,\"\/bin\/newressu \",14)) {\n\tif((fp2=popen(command, \"r\"))!=NULL) {\n\t  dbs_html_printf(\"&lt;code&gt;\");\n\t  while(fgets(buffer,sizeof(buffer),fp2)!=NULL) {\n#ifdef DEBUG8\n\t    fprintf(stdout,\"\\\"%s\\\"\",buffer);\n#endif\n\t    p=buffer;\n\t    while(*p!='\\0') {\n\t      if(*p!='-') \n\t\tdbs_html_printf(\"%c\",*p);\n\t      else {\n\t\tif(safari)\n\t\t  dbs_html_printf(\"&amp;#8209;\");\n\t\t\/\/dbs_html_printf(\"&amp;minus;\");\n\t\t\/\/dbs_html_printf(\"&amp;ndash;\");\n\t\t\/\/dbs_html_printf(\"&amp;hyphen;\");\n\t\t\/\/dbs_html_printf(\"&amp;#45;\");\n\t\telse\n\t\t  dbs_html_printf(\"&amp;minus;\");\n\t      }\n\t      p++;\n\t    } \/\/ while(*p!='\\0') {\n\t    \/\/dbs_html_printf(\" \");\n\t    \/\/dbs_html_printf(\"\\n\");\n\t    \/\/dbs_html_printf(\"&lt;br&gt;\");\n\t  } \/\/ while(fgets(\n\t  dbs_html_printf(\"&lt;\/code&gt;\");\n\t  fclose(fp2);\n\t} \/\/ if((fp2\n      } else { \/\/ if(!strncmp(command\n\tif(useragent)\n\t  dbs_html_printf(\"%s\",command);\n\telse if(strstr(command,\"&lt;h1&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h2&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h3&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h4&gt;\")!=NULL )\n\t  dbs_html_printf(\"%s\",command);\n      } \/\/ if(strncmp\n    } \/\/ while(fgets\n    fclose(fp1);\n  } \/\/ if((fp1=fopen\n  if((fp1=fopen(\"ressuoriginal.html\",\"r\"))!=NULL) {\n    while(fgets(buffer,sizeof(buffer),fp1)!=NULL)\n      if(buffer&#91;0]!=';')\n\tdbs_html_printf(\"%s\",buffer);\n    fclose(fp1);\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavassa palvelimen kutsumat ressu4 funktiot: dbs_html_set valitsee puskurin, johon rivit tulostetaan t\u00e4ss\u00e4 otsake(0) tai payload(1) (html.c). dba_loop tulostaa html sivun, dba_loop2 laskee sivun merkkien lukum\u00e4\u00e4r\u00e4n (Content-Length) otsakkeelle. N\u00e4iden v\u00e4liss\u00e4 palvelin suorittaa html prettyprinter:in josta my\u00f6hemmin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dba_loop()\n{\n  html_clear_all();\n  if(!strcmp(htmlfileextension,\"ico\") ||\n     !strcmp(htmlfileextension,\"png\")) {\n    dbs_html_set(0);\n    dbs_html_printf(\"HTTP\/1.0 404 Not Found\\r\\n\");\n    \/\/dbs_html_printf(\"Location: \\r\\n\");\n    \/\/dbs_html_printf(\"Server: %s\\r\\n\", programname);\n  } else {  \n    dbs_html_set(0);\n    dbs_html_printf(\"HTTP\/1.0 200 OK\\r\\n\");\n    dbs_html_printf(\"Location: \\r\\n\");\n    dbs_html_printf(\"Server: %s\\r\\n\", programname);\n    dbs_html_printf(\"Date: %s\\r\\n\", htmltime);\n    \n    dbs_html_set(1);\n    \n    dbs_html_printf(\"&lt;!doctype html&gt;\\r\\n\");\n    dbs_html_printf(\"&lt;html lang=\\\"fi\\\"&gt;\");\n    \n    dbs_html_printf(\"&lt;head&gt;\");\n    dbs_html_printf(\"&lt;meta charset=\\\"utf-8\\\"&gt;\");\n    dbs_html_printf(\"&lt;title&gt;%s&lt;\/title&gt;\",proctitle);\n    dbs_html_printf(\"&lt;meta name=\\\"author\\\" content=\\\"Jari Kuivaniemi\\\"&gt;\");\n    dbs_html_printf(\"&lt;meta name=\\\"copyright\\\" content=\\\"Jari Kuivaniemi\\\"&gt;\");\n    dbs_html_printf(\"&lt;meta name=\\\"format-detection\\\" content=\\\"telephone=no\\\"&gt;\"); \/\/ Safari\n    dbs_html_printf(\"&lt;meta name=\\\"format-detection\\\" content=\\\"telephone=no\\\"\/&gt;\"); \/\/ Safari\n    dbs_html_printf(\"&lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"&gt;\");\n    dbs_html_printf(\"&lt;\/head&gt;\");\n    \n    dbs_html_printf(\"&lt;body&gt;\");\n    \n    ressu4_app();\n\n    dbs_html_printf(\"&lt;p&gt;%s\", programname);\n    dbs_html_printf(\",  sha256(%s)\", htmldigest);\n    dbs_html_printf(\"&lt;\/p&gt;\");\n\n    dbs_html_printf(\"&lt;\/body&gt;\");\n  \n    dbs_html_printf(\"&lt;\/html&gt;\");\n  }\n}<\/code><\/pre>\n\n\n\n<p>Prettyprinter formatoi html scriptin uudestaan, ja t\u00e4ll\u00f6in payload puskurin pituus muuttuu. Content-Length lasketaan vasta prettyprinter:in j\u00e4lkeen: Lis\u00e4ksi tulostetaan otsakkeen ja payloadin v\u00e4lill\u00e4 oleva cr-lf-cr-lf sarja.<\/p>\n\n\n\n<p>Content-Length riville lasketaan kaikki muut puskurit paitsi 0 eli otsake.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dba_loop2()\n{\n  int len;\n\n  dbs_html_set(0);\n\n  len=strlen(html_get_string(1)) +\n    strlen(html_get_string(2)) +\n    strlen(html_get_string(3)) +\n    strlen(html_get_string(4)) +\n    strlen(html_get_string(5)) +\n    strlen(html_get_string(6)) +\n    strlen(html_get_string(7)) +\n    strlen(html_get_string(8));\n  log_printf(\"Content-Length: %d\\n\",len);\n  dbs_html_printf(\"Content-Length: %d\", len);\n  dbs_html_printf(\"\\r\\n\\r\\n\");\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4m\u00e4 on klassinen joka ohjelmaan kuuluva write only p\u00e4tk\u00e4. Se k\u00e4y asiakas-ohjelman muodostaman html-scriptin l\u00e4pi, ja muotoilee sen lis\u00e4ten sisennykset. Ohjelmassa on iso iffi, jossa on erilaiset k\u00e4sittelyt alkutagille, lopputagille ja teksteille. Ennen koodia muotoiltu html-scripti:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!doctype html&gt;\n&lt;html lang=\"fi\"&gt;\n\t&lt;head&gt;\n\t\t&lt;meta charset=\"utf-8\"&gt;\n\t\t&lt;title&gt;Ressu random numbers&lt;\/title&gt;\n\t\t&lt;meta name=\"author\" content=\"Jari Kuivaniemi\"&gt;\n\t\t&lt;meta name=\"copyright\" content=\"Jari Kuivaniemi\"&gt;\n\t\t&lt;meta name=\"format-detection\" content=\"telephone=no\"&gt;\n\t\t&lt;meta name=\"format-detection\" content=\"telephone=no\"\/&gt;\n\t\t&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n\t&lt;\/head&gt;\n\t&lt;body&gt;\n\t\t&lt;h1&gt;Ressu random numbers (3rd edition)&lt;\/h1&gt;\n\t\t&lt;p&gt;The next chapter consists of characters that try to resemble throws of a 64 sided dice as closely\n\t\tas possible. Characters have numbers from '0' to '9' (10 entries), uppercase letters from 'A' to 'Z'\n\t\t(26 entries), lowercase letters 'a' to 'z' (26 entries), '-' and '_' (2 entries). Total is\n\t\t10+26+26+2 = 64 values. Characters are grouped into sets of 8 each. Throws are random, so you cannot\n\t\tdeduce value from previous or next value(s).&lt;\/p&gt;\n\t\t&lt;h3&gt;Newressu random numbers&lt;\/h3&gt;\n\t\t&lt;code&gt;_&amp;minus;MnnU0t zMILwAzz _2QvgUvn ZiTlUvUa NFQ8SAWH Y16F&amp;minus;WfQ SuNISxyL pcfa1veB\n\t\tSwY&amp;minus;Sv_s nGU8zPEL eEJXLzHh CM88ViFN dQOdn8G2 NlGtAMYI iGpPs7SH bzRse_PQ CZ0qnLpd\n\t\tcARyjtSX 0WAhwrf&amp;minus; i0kNx3W2 9Z6Acz5q 8Ik0hsxy fHHT1jRD XXbwNO4_ AsIbJD7O MSiJX&amp;minus;wv\n\t\tbDkAVVcu r9PHGcS0 IzCtSytI g8E565wO GyPga1LE 4aud&amp;minus;VdS RHJDDQL&amp;minus; CLd4oo4L oX9evdxW\n...\n\t\tkLq1ipRv gAx50HPh DmYWlnC6 YE3cFz6n SUXaGxNO VomWkvak PCIi0TZ0 &amp;minus;Aji6Ic_ o97UH&amp;minus;cf\n\t\tc&amp;minus;bcT66x DBJZfuyP 0DInhV72 h3tg10Ut EemFvFM2 Vgqb7dTT rRu5cieb d525p4Mt P7dl5NK&amp;minus;\n\t\tgz6nADAr b3NmlG2p yX6J2GiL 3_aQPB&amp;minus;F 2btVCtEI IVFKckK9 Z5Td_Efe IytGwbob kHZoXbOC\n\t\txVRHgtq7&lt;\/code&gt;\n\t\t&lt;h3&gt;Random digits&lt;\/h3&gt;\n\t\t&lt;code&gt;80313684 35745972 00745113 11965506 39675183 31627471 96260247 63282566 20584179\n\t\t75300052 77578427 13585911 50498322 42744053 50358954 49905271 58259581 03942398 26828764\n\t\t04379099 26025983 87357515 02820498 26270068 02318240 95638924 41550156 07366984 73725656\n\t\t95465312 57023555 71860218 26527096 64829893 47562651 26652479 99838964 11307190 84028643\n...\n\t\t43822905 45192876 80902045 91287056 62271398 18354252 09842608 58491390 36494150 06737249\n\t\t79097332 78982704 51002048 98004383 30727141 69582220 67771805 16857046 37252823 02127291\n\t\t75806553 92973387 12285285 12582540 79234018 40546782 14578681 84859328 04505090 18357251\n\t\t99180783 65733520 48631827 20279470 04679868 94102024 34890821 98137030 73108089 41263404&lt;\/code&gt;\n\t\t&lt;h3&gt;Random uppercase letters&lt;\/h3&gt;\n\t\t&lt;code&gt;AUBQMVVZ IDBFUNFU EWSQJXLI PESJYIUG RJKITODE IDWXMVAG KDEIQBJV YWVBTERK KXNHHMRD\n\t\tJTDHVEQW VQUNSMSX JERKHYVQ WATLYHIM HOXBQRSX AWZEBOMC IURFFOEZ NICWPOBT YLHFCFFK LNYDTXXE\n\t\tGVRVMCFM JZWLHOZF GDOYZIPU QARHVPHO PEAEHOIJ LWSAJEPN UWOAICBV OEZUEKYD PTCVQCUM EDLYCDOQ\n\t\tRAANTTVG TTXVXNFM NZOLDAJS FTWIFKFE UUTDBSRA DAJGRZCY VDPVBAVM SYLLMMRQ MLAMPJOJ ZLPEMKSE\n\t\tISYDWSBF DHQMLMBM IUWRCHAZ KEZTQHWT NSFCBRDJ IVYCEYHG BRBJZOIP GRDHFPHE MALPLXHN SHPGMKIB\n...\n\t\tCLLLBWQV BBNZRWXD HUWJBBJR WEJYWLIJ NAJODNVH JRVLIWTY OGLLYFSF JRPMMCSY JLFJKQTO YUOZUKUM\n\t\tWMGKGWET SRFZZGFK WSHLWUPX RKALRMFV XBHHHTTF GJNXCHAY FWCDAGCI BRGYQJKD XNTHBNUY YOLWRYCK\n\t\tMCLIUAKU WERPDLSD WBFPJWGQ EUTNUJII VAJOLVPV ATVOVPQT PFUCXWZL JXYGYXOG EXMYXKYT EPOZVXFZ\n\t\tWTHXVPUF OMMTIXXE BVNYVSVB MLZHOZNT NGZGYCRN SDBVJUEJ CCUCJBEF GZBFSXET PRRRMSBI PVBSQKKQ&lt;\/code&gt;\n\t\t&lt;h3&gt;Random lowercase letters&lt;\/h3&gt;\n\t\t&lt;code&gt;ncdxfqnc aouweehi hamohwtd rhccumkp zvsxtkbm kmkncixk poucraok gvgxnqmt xjddvykh\n\t\tkqackiak krojmfsn gjgonlio sptakqqu jzzwsqmw bvkexphf exujzvtl moraehkn snthsdwb yvpcptom\n\t\troifedpi wzglxgvq rcuwbbje qbbohgvy pxqxsnmu mccldckk idcwlths vnfgeeaz xjnhwxyq gbuscedb\n\t\tzowriyfe pjbqeoad hrqynigj vhrjlyui iokaxxmo zafimxzv pdjgldxs ocmaljlz mjbvdofr bhwudqkg\n\t\tzzjgygoz fjhrqyru nwuivcqy vyfjsmzy xxznieam omzgczbu gcxppsqv azpworcc hbyyjcga hinulxnt\n...\n\t\tmjoxwldd aczipohr diltdgol olrccnqg nkmxjieo ttyxznjf zqzteonk inalvyvq esystahu zeesrmdv\n\t\tpbdazwoy bkivauss tkvnizfk rwtsdsny otcdoaxv ttoewgtf utjkaqpc vqcbedri gluifwmx sevbupal\n\t\tgowmzyia ruwvzzrg uqgmskzv onwwurib fwwginyp dklxxfwf hywmhqlc cyyfyenb hddfngsw zybqvptd\n\t\tdwaixegk drrwmccs vouyjvwb spfxctdn onyjwcap zprretng ccemcduj lnrngwpj rsrqpucm onbeixhh&lt;\/code&gt;\n\t\t&lt;h2&gt;Random characters in number systems&lt;\/h2&gt;\n\t\t&lt;h3&gt;Random binary digits&lt;\/h3&gt;\n\t\t&lt;p&gt;Following binary numbers are eight bits from 0 to 255 decimal. From right to left the bit\n\t\tmultipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal. So 10000000b is 128d, 11111111b is\n\t\t255d, 00000010b is 2d, 00000011b is 3d etc. Here d after number means of course decimal. Digit\n\t\tnumbers, b in 2^b, vary from 0 to 7.&lt;\/p&gt;\n\t\t&lt;code&gt;10000100 10001011 00000101 01010110 10111101 01001011 01001010 01111100 10010111\n\t\t11010010 11110111 11011111 00001100 10110101 10010110 11100011 01010001 10000101 00010010\n\t\t10111111 10010101 01100011 01110110 10101010 01001100 10100011 11101101 00001011 10110011\n\t\t10100001 11011101 10000000 10100100 01000010 11001000 11101110 00100000 00000010 01111000\n...\n\t\t10100011 11001000 01101010 11101001 10011001 10110010 11011110 11110001 11010110 00011000\n\t\t01000100 00010011 00100100 01100010 11100110 01011101 10000110 10111000 11010110 11001111\n\t\t01111101 10001000 00010110 11011010 10011101 11111001 01101011 00111011 00111111 10000111\n\t\t11010111 11110010 10001110 11100011 11101010 00101111 01100101 11100110 10111100 11010011&lt;\/code&gt;\n\t\t&lt;h3&gt;Random octal digits&lt;\/h3&gt;\n\t\t&lt;p&gt;These octal numbers are also from 0 to 255 decimal (0 to 377 octal). From right to left octal digit\n\t\tmultipliers are 1, 8, 64 (8^o) in decimal. Here 377o is 255d, 010o is 8d, 100o is 64d. Each octal digit\n\t\tcontains 3 binary bits, and 377o can be grouped in binary like this 011 111 111.&lt;\/p&gt;\n\t\t&lt;code&gt;102 025 024 061 277 033 242 213 004 334 107 102 144 367 150 247 237 016 217 134 042 370 267 162 175 301\n\t\t230 373 125 115 272 123 014 026 112 351 047 132 252 326 053 344 073 364 174 017 150 324 326 040 224 231 165 173\n\t\t143 011 160 175 143 010 021 136 076 017 231 164 135 167 313 021 245 230 300 234 314 267 150 271 367 352 042 177\n\t\t125 070 337 074 061 342 117 353 176 331 372 100 152 110 012 340 016 362 161 322 323 032 227 061 047 215 006 216\n\t\t003 157 212 001 005 375 326 125 227 154 354 345 063 214 263 120 257 255 037 276 305 234 214 137 277 075 134 267\n...\n\t\t011 343 304 205 146 152 276 223 110 115 334 250 115 173 027 371 376 317 133 234 107 352 053 155 212 044 032 253\n\t\t323 127 347 231 066 011 026 366 102 260 227 344 231 153 044 371 115 264 352 237 330 071 322 156 173 307 133 065\n\t\t066 245 275 270 321 145 222 036 140 060 362 077 270 166 330 117 173 017 223 066 170 304 063 221 036 223 165 073\n\t\t357 066 353 334 116 025 201 360 321 200 073 020 077 156 141 162 011 126 157 344 111 240 164 315 122 252 137 244\n\t\t072 015&lt;\/code&gt;\n\t\t&lt;h3&gt;Random decimal digits&lt;\/h3&gt;\n\t\t&lt;p&gt;These decimal numbers are from 0 to 99999. From right to left decimal digit multipliers are 1, 10,\n\t\t100, 1000 and 10000 (10^d).&lt;\/p&gt;\n\t\t&lt;code&gt;24419 31184 02393 04466 14613 16133 79118 27250 72887 08069 71932 68501 99089 75389 78600\n\t\t27515 57258 86941 81577 34050 41156 02253 30409 02904 90536 95086 10717 44661 01654 28649 86938\n\t\t26666 79745 87626 91850 86989 19827 11135 23508 12355 64724 04439 52568 63139 02473 05829 50914\n\t\t32411 25782 02409 28444 63704 68532 86493 85871 00441 49962 73554 67031 15180 33919 12141 79904\n...\n\t\t38024 67921 62186 26159 42438 04270 78192 54364 96314 96670 15650 08550 35165 55312 71523 22212\n\t\t72163 37309 41644 68769 28343 04812 81462 73380 88334 07695 95749 74636 93787 97867 26227 76150\n\t\t78417 48706 88812 68138 53680 08453 31168 40950 14859 98299 53943 96364 12848 63945 66586 98180\n\t\t15320 25092 79344 35777 71710 10193 88538 72530 37765 40684 49186 99440 96100 79970 63910 57759\n\t\t00684 63359 12128 10759 83732 87712 36846 03493 36866 61989 50384&lt;\/code&gt;\n...\n\t\t&lt;h2&gt;Technical&lt;\/h2&gt;\n\t\t&lt;p&gt;This version runs newressu new for all of the previous random number chapters (25 runs), so the\n\t\tbuffer is empty in the beginning of the chapter runs. This whole page is created (including\n\t\trandomness) after your network query is received, so time newressu runs is quite reasonable.&lt;\/p&gt;\n\t\t&lt;p&gt;This version does random skips on clock material, which makes it harder to guess it. Ressu skips\n\t\t0-255 bytes every ~1000 bytes. This version also is ressu only, there is no whitening or combining of\n\t\tother generators.&lt;\/p&gt;\n\t\t&lt;p&gt;Original url(s):&lt;br&gt;\n\t\t\tressu:\n\t\t\t&lt;a href=\"https:\/\/moijari.com:5006\"&gt;https:\/\/moijari.com:5006&lt;\/a&gt;(third edition)&lt;br&gt;\n\t\t\tressu:\n\t\t\t&lt;a href=\"https:\/\/moijari.com:5005\"&gt;https:\/\/moijari.com:5005&lt;\/a&gt;(second\n\t\t\tedition)&lt;br&gt;\n\t\t\tressu:\n\t\t\t&lt;a href=\"https:\/\/moijari.com:5001\"&gt;https:\/\/moijari.com:5001&lt;\/a&gt;(first edition)&lt;br&gt;\n\t\t\tterttu:\n\t\t\t&lt;a href=\"https:\/\/moijari.com:5004\"&gt;https:\/\/moijari.com:5004&lt;\/a&gt;\n\t\t&lt;\/p&gt;\n\t\t&lt;p&gt;Ressu4 version 0.2 \u00a9,\n\t\tsha256(1b1c265ad48cefcdc43032f475775ab3ef68f2348e24f94f3282dce5e1e89e40)&lt;\/p&gt;\n\t&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<p>Here is prettyprinter code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG36 2\n#define aDEBUG37 2\n\nvoid html_indent(unsigned char *p2)\n{\n  int space, ch, tags, tagfound, intag, inchar;\n  unsigned char *p,*q,*q2,name&#91;32],tag&#91;48];\n\n  p=p2;\n  ch=0;\n  indent=0;\n  inchar=0;\n  while(*p!='\\0') {\n    space = 0;\n    while(*p=='\\r' || *p=='\\n' || *p=='\\t' || *p==' ') {\n      p++;\n      space = 1;\n    }\n    if(!strncmp(p,\"&lt;br&gt;\",4)) {\n      p+=4;\n      html_printf(\"&lt;br&gt;\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;br&gt;\");\n#endif\n      printedchars+=4;\n      \n      while(*p=='\\r' || *p=='\\n' || *p=='\\t' || *p==' ')\n\tp++;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;nextchar:%c]\",*p);\n#endif\n      if(strncmp(p,\"&lt;\/\",2))\n\thtml_out_crlf();\n    }\n\n    if(!strncmp(p,\"&lt;\/\",2)) { \/\/ Check for end tag\n\n      q2 = p;\n      p += 2;\n      q = p;\n      html_parse_name(sizeof(name), name, &amp;q);\n      q = q2 - 1;\n      tags = 0;\n      tagfound = 0;\n\n      \/\/ Search for start tag backward\n      sprintf(tag,\"&lt;%s\", name);\n      while(q &gt;= p2) {\n        if(*q == '&lt;') {\n          if(!strncmp(tag, q, strlen(tag))) {\n#ifdef DEBUG36    \n            fprintf(stdout,\"&#91;tag:%s]\", tag);\n#endif\n            tagfound = 1;\n            break;\n          } else\n            tags++;\n        }\n        q--;\n      }\n      if(tags &amp;&amp; indent &gt; 0) {\n        indent--;\n#ifdef DEBUG36\n        fprintf(stdout,\"&#91;indent:%d]\",indent);\n        fprintf(stdout,\"&#91;tagfound:%d]\",tagfound);\n#endif\n        html_out_crlf();\n      }\n      html_printf(\"&lt;\/\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;\/\");\n#endif\n      space = 0;\n      intag = 1;\n      inchar = 0;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n      printedchars+=2;\n\n    } else if(*p=='&lt;') { \/\/ Check for start tag\n\n      p++;\n      q = p;\n      html_parse_name(sizeof(name),name,&amp;q);\n      tags = 0;\n      tagfound = 0;\n\n      \/\/ Search for end tag forward\n      sprintf(tag,\"&lt;\/%s\",name);\n      while(*q!='\\0') {\n        if(*q=='&lt;') {\n          if(!strncmp(tag, q, strlen(tag))) {\n#ifdef DEBUG36\n            fprintf(stdout,\"&#91;tag:%s]\",tag);\n#endif\n            tagfound = 1;\n            break;\n          } else\n            tags++;\n        }\n        q++;\n      }\n      html_out_crlf();\n      if(tags &amp;&amp; tagfound) {\n        indent++;\n#ifdef DEBUG36\n        fprintf(stdout,\"&#91;indent:%d]\",indent);\n        fprintf(stdout,\"&#91;tagfound:%d]\",tagfound);\n#endif\n      }\n      html_printf(\"&lt;\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;\");\n#endif\n      space = 0;\n      intag = 1;\n      inchar = 0;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n      printedchars++;\n    } else if((isprint(*p) || *p&gt;=128) &amp;&amp; *p!='\\0') {\n      if(!inchar &amp;&amp; !intag) {\n\tinchar=1;\n#ifdef DEBUG36\n\tfprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n\t\/\/html_out_crlf();\n      }\n      int count=0;\n      for(q=p;(isprint(*q) || *q&gt;=128) &amp;&amp; *q!='\\0';q++) {\n\tif(*q=='\\r' || *q=='\\n' || *q=='\\t' || *q==' ')\n\t  break;\n#ifdef DEBUG36\n\tfprintf(stdout,\"%c\",*q);\n#endif\n\tcount++;\n      }\n#ifdef DEBUG36\n      fprintf(stdout,\"(%d)\",count);\n#endif\n    }\n\n    int chars = 0;\n\n    \/\/ calculate number of chars\n    q = p;\n    while((*q!='&lt;' &amp;&amp; (isprint(*q) || *q&gt;=128)) &amp;&amp; *q!='\\0') {\n      if(*q=='\\r' || *q=='\\n' || *q=='\\t' || *q==' ')\n        break;\n      if(*q&lt;0x80 || *q&gt;0xbf) \/\/ utf8 too\n        chars++;\n      if(*q=='&gt;')\n\tbreak;\n      q++;\n    }\n\n    \/\/ print line break if needed\n    if(indent*8+printedchars+chars &gt; 100 &amp;&amp; !intag) {\n      html_out_crlf(); \/\/ print nl+indent\n      space = 0;\n    }\n    \n    \/\/ print space if needed\n    if(ch != '&gt;' &amp;&amp; \/\/ no space after tag\n       *p != '&lt;' &amp;&amp; \/\/ no space before tag\n       printedchars &gt; 0 &amp;&amp;\n       space) {\n      html_printf(\" \");\n#ifdef DEBUG36\n      fprintf(stdout,\" \");\n#endif\n      space = 0;\n    }\n\n    \/\/print the string\n    while((*p != '&lt;' &amp;&amp; (isprint(*p) || *p &gt;= 128)) &amp;&amp; *p != '\\0') {\n      if(*p == '&gt;') {\n        intag = 0;\n      }\n      if(*p == '\\r' || *p == '\\n' || *p == '\\t' || *p == ' ')\n        break;\n      ch = *p;\n      html_printf(\"%c\", *p);\n#ifdef DEBUG36\n      fprintf(stdout,\"%c\",*p);\n#endif\n      printedchars++;\n      if(*p=='&gt;') {\n\tp++;\n\tbreak;\n      }\n      p++;\n    }\n#ifdef DEBUG36\n    fprintf(stdout,\"(%d)\",chars);\n#endif\n  } \/\/while(*p!='\\0')\n#ifdef DEBUG37\n  fprintf(stdout,\"%s\",html&#91;html_now]);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Asiakas palvelin kutsuu newressu komentoa saadakseen satunnaisbittej\u00e4. Seuraavassa newressun p\u00e4\u00e4muutos, eli satunnaisten bittien ohitus kellojonossa:<\/p>\n\n\n\n<p>Ohituksen (skip) satunnaisuutta ei tietenk\u00e4\u00e4n voi ottaa puskurista, koska silloin se ei vaikuttaisi ollenkaan kahteen samalla kellojonolla tehtyyn ajoon. T\u00e4ss\u00e4 sit\u00e4 varten lasketaan puskurimerkin numero, jolla varsinainen 8 bittinen satunnaismerkki luetaan puskurista. Puskurimerkin numeroon lasketaan muunmuassa kellon sekunnit (katso koodi).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define MORESECURE 2\n#define aDEBUG3 2\n\nstatic unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  unsigned char ch;\n\n  ch=ressu_clockbyte2();\n  \n#ifdef MORESECURE\n  static unsigned int rndbits2pausecount=1000, rndbits2pausebase=0;\n  \n  if(--rndbits2pausecount == 0) {\n#ifdef FORT\n    if(input == INPUT_FORT ||\n       input == INPUT_FORTXOR)\n      rndbits2pausebase += cvar&#91;0] + 256 * cvar&#91;1];\n#endif    \n    rndbits2pausebase = rndbits2pausebase +\n      rndbits2pausecount +\n      clockbytes +\n      genbytes +\n      gent_pos +\n      time(NULL) +\n      ch;\n\n    int skip=ressut&#91;rndbits2pausebase % ressut_bytes];\n\n    while(skip&gt;0) { \/\/ compare usleep(skip);\n      ch=ressu_clockbyte2();\n      skip--;\n    }\n\n    rndbits2+=8;\n    \n    rndbits2pausecount=500+ressut&#91;(rndbits2pausebase + 1) % ressut_bytes]*4; \/\/ value 500-1500\n#ifdef DEBUG3\n    fprintf(stdout,\"\\n%05d\",pausecount);\n    newressu_output=1;\n#endif\n  }\n#ifdef DEBUG3\n  fprintf(stdout,\" %02x\",ch);\n  newressu_output=1;\n#endif\n\n#endif \/\/ #ifdef MORESECURE\n  return(ch);\n}<\/code><\/pre>\n\n\n\n<p>Newressua on nopeutettu hieman lis\u00e4\u00e4m\u00e4ll\u00e4 v\u00e4liinputoaja sanan pituuksille k\u00e4sittelyit\u00e4: Ennen t\u00e4ss\u00e4 rutiinissa oli k\u00e4sittely vain yksimerkkisille (byte) 2 merkkisille (short), 4 merkkisille (int) ja 8 merkkisille (long) tietotyypeille. Uudessa versiossa on erilliset k\u00e4sittelyt my\u00f6s 3, 5, 6 ja 7 merkkisille satunnaislukusanoille.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Little faster on middle byte numbers (3,5,6,7),\n\/\/ try --rand &amp; --timer\n#define GENMIDBYTES 2\n#define aDEBUG19 2\n\nint ressu_genbyte_limit(int limit) \/\/ 1 byte\n{\n  int c;\n  while((c=ressu_genbyte()) &gt;= (0x100\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" byte %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nint ressu_genshort() \/\/ 2 bytes\n{\n  return(ressu_genbyte() | ressu_genbyte()&lt;&lt;8);\n}\n\nint ressu_genshort_limit(int limit) \/\/ 2 bytes\n{\n  int c;\n  while((c=ressu_genshort()) &gt;= (0x10000\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" short %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#ifdef GENMIDBYTES\n\nint ressu_gen3bytes() \/\/ 3 bytes\n{\n  return(ressu_genshort() | ressu_genbyte()&lt;&lt;16);\n}\n\nint ressu_gen3bytes_limit(int limit) \/\/ 3 bytes\n{\n  int c;\n  while((c=ressu_gen3bytes()) &gt;= (0x1000000\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 3 bytes %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#endif \/\/ #ifdef GENMIDBYTES\n\nunsigned int ressu_genint() \/\/ 4 bytes\n{\n  return(ressu_genshort() | ressu_genshort()&lt;&lt;16);\n}\n\nunsigned int ressu_genint_limit(unsigned long limit) \/\/ 4 bytes\n{\n  unsigned int c;\n  while((c=ressu_genint()) &gt;= (((unsigned long)0x100000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" int %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#ifdef GENMIDBYTES\n\nunsigned long ressu_gen5bytes() \/\/ 5 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_genbyte())&lt;&lt;32);\n}\n\nunsigned long ressu_gen5bytes_limit(unsigned long limit) \/\/ 5 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen5bytes()) &gt;= (((unsigned long)0x10000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 5 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nunsigned long ressu_gen6bytes() \/\/ 6 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_genshort())&lt;&lt;32);\n}\n\nunsigned long ressu_gen6bytes_limit(unsigned long limit) \/\/ 6 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen6bytes()) &gt;= (((unsigned long)0x1000000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 6 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nunsigned long ressu_gen7bytes() \/\/ 7 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_gen3bytes())&lt;&lt;32);\n}\n\n#define aDEBUG22\n\nunsigned long ressu_gen7bytes_limit(unsigned long limit) \/\/ 7 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen7bytes()) &gt;= (((unsigned long)0x100000000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 7 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#endif \/\/ #ifdef GENMIDBYTES\n\nunsigned long ressu_genlong() \/\/ 8 bytes\n{\n  return(((unsigned long)ressu_genint()) | ((unsigned long)ressu_genint())&lt;&lt;32);\n}\n\nunsigned long ressu_genlong_limit(unsigned long limit) \/\/ 8 bytes\n{\n  unsigned long c;\n  while((c=ressu_genlong()) &gt;= (((unsigned long)0xffffffffffffffff)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" long %lx(%lu)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#define aDEBUG24 2\n\nunsigned long ressu_gen_limit(unsigned long limit)\n{\n  unsigned long c;\n\n  if(limit&lt;=0x100) \/\/ 1 byte\n    c=ressu_genbyte_limit(limit);\n  else if(limit&lt;=0x10000) \/\/ 2 bytes\n    c=ressu_genshort_limit(limit);\n#ifdef GENMIDBYTES\n  else if(limit&lt;=0x1000000) \/\/ 3 bytes\n    c=ressu_gen3bytes_limit(limit);\n#endif\n  else if(limit&lt;=(unsigned long)0x100000000) \/\/ 4 bytes\n    c=ressu_genint_limit(limit);\n#ifdef GENMIDBYTES\n  else if(limit&lt;=(unsigned long)0x10000000000) \/\/ 5 bytes\n    c=ressu_gen5bytes_limit(limit);\n  else if(limit&lt;=(unsigned long)0x1000000000000) \/\/ 6 bytes\n    c=ressu_gen6bytes_limit(limit);\n  else if(limit&lt;=(unsigned long)0x100000000000000) \/\/ 7 bytes\n    c=ressu_gen7bytes_limit(limit);\n#endif\n  else if(limit&lt;=(unsigned long)0xffffffffffffffff) \/\/ 8 bytes\n    c=ressu_genlong_limit(limit);\n  else\n    c=-1;\n\n#ifdef DEBUG24\n  fprintf(stdout,\"\/%ld\/\",c);\n#endif\n\n  return(c);\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavalla p\u00e4\u00e4ohjelmasta l\u00f6ytyv\u00e4ll\u00e4 &#8211;screen optiolla voidaan tehd\u00e4 satunnaismerkkej\u00e4 n\u00e4yt\u00f6llinen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  for(c=1;c&lt;argc;c++) {\n    if(!strncmp(\"-\",argv&#91;c],1)) {\n...\n      } else if(!strncmp(\"--screen\",argv&#91;c],8)) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\tlines = w.ws_row-1;\n\twords = 0;\n\tscreen = 1;\n#ifdef DEBUG71\n\tfprintf(stdout,\"screencolumns:%d\",chars);\n\tfprintf(stdout,\" screenlines:%lld\\n\",lines);\n#endif\n<\/code><\/pre>\n\n\n\n<p>Seuraavalla voidaan tulostaa heksadesimaalisatunnaismerkkej\u00e4 isoilla kirjaimilla:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  for(c=1;c&lt;argc;c++) {\n    if(!strncmp(\"-\",argv&#91;c],1)) {\n...\n      } else if(!strcmp(\"-X\",argv&#91;c])) {\n\tdigits = \"0123456789ABCDEF\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 16;\n<\/code><\/pre>\n\n\n\n<p>Seuraavilla voidaan tulostaa japanilaisia, kiinalaisia ja korealaisia satunnaismerkkej\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      } else if(!strcmp(\"--jp\",argv&#91;c])) { \/\/ japanese hiragana alphabet\n\n\tdigits = NULL;\n\tdigits_add_string(&amp;digits,\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\");\n\tdigits_add_string(&amp;digits,\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\");\n\tdigits_add_limits(&amp;digits,0x4e00,0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\n\t\n      } else if(!strcmp(\"--jp1\",argv&#91;c]) \/\/ japanese hiragana alphabet\n\t\t||!strcmp(\"--hir\",argv&#91;c])) { \/\/ japanese hiragana alphabet\n\tdigits=\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\";\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\n      } else if(!strcmp(\"--jp2\",argv&#91;c]) \/\/ japanese katakana alphabet\n\t\t||!strcmp(\"--kat\",argv&#91;c])) {  \/\/ japanese katakana alphabet\n\tdigits=\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\";\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\n      } else if(!strcmp(\"--cn\",argv&#91;c]) \/\/ chinese alphabet \n\t\t||!strcmp(\"--jp3\",argv&#91;c]) \/\/ japanese kanji alphabet\n\t\t||!strcmp(\"--kan\",argv&#91;c])) { \/\/ japanese kanji alphabet\n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits,0x4e00,0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\n      } else if(!strcmp(\"--kor\",argv&#91;c])) { \/\/ korean alphabet \n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits,0xac00,0xd7a3);   \/\/ Hangul Syllables (AC00\u2013D7A3)\n\t\/\/digits_add_limits(&amp;digits,0x1100,0x11ff); \/\/ Hangul Jamo (1100\u201311FF)\n\t\/\/digits_add_limits(&amp;digits,0x3130,0x318f); \/\/ Hangul Compatibility Jamo (3130\u2013318F)\n\t\/\/digits_add_limits(&amp;digits,0xa960,0xa97f); \/\/ Hangul Jamo Extended-A (A960\u2013A97F)\n\t\/\/digits_add_limits(&amp;digits,0xd7b0,0xd7ff); \/\/Hangul Jamo Extended-B (D7B0\u2013D7FF)\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;<\/code><\/pre>\n\n\n\n<p>Mallituloste japanin satunnaisista merkeist\u00e4: (hirakana, katakana ja kanji)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ newressu --hir\n00000 \u306b\u304d\u3053\u306d\u306e\u3044\u306b\u307a\u3067\u3044\u3079\u3048\u3044\u307b\u3053\u3065\u305a\u304a\u307c\u3061\u3068\u306c\u3079\u3082\u307f\u3074\u3084\u3084\u3088\u3070\u308a\u3084\n00001 \u3063\u3059\u3094\u3061\u3067\u308f\u3066\u304a\u3096\u3051\u3091\u3083\u3074\u3044\u3042\u3076\u3069\u3078\u305e\u304b\u3084\u306e\u3047\u304d\u3080\u3052\u3060\u3071\u306e\u305e\u308d\u3061\n00002 \u3064\u307a\u3051\u3096\u3090\u3060\u3082\u3092\u3085\u3042\u306b\u3060\u3074\u3063\u3041\u3067\u3052\u3095\u3069\u305f\u3045\u3048\u3043\u3083\u308c\u3068\u3066\u3051\u306f\u3086\u3047\u304b\n00003 \u3064\u305a\u3070\u3047\u307a\u3053\u3043\u3052\u3042\u305d\u3077\u3091\u3057\u308f\u3052\u3073\u3060\u308d\u3070\u308d\u3053\u307d\u3079\u3069\u305f\u3076\u3082\u3061\u3054\u306b\u3087\u306a\n00004 \u3064\u306b\u3060\u3049\u3084\u3083\u3050\u3083\u3044\u307b\u308a\u308a\u3086\u307a\u305d\u305c\u3094\u3079\u3090\u3071\u3063\u3049\u3054\u3051\u3053\u306f\u3086\u3043\u3072\u306a\u3071\u3084\n00005 \u3085\u3081\u308d\u3063\u307a\u307a\u3060\u3078\u304e\u3043\u305f\u3044\u308f\u306e\u3070\u306f\u305c\u3047\u3091\u3083\u3079\u304f\u3061\u307e\u306c\u3070\u3072\u305e\u3052\u3063\u3070\u306e\n00006 \u3086\u305d\u3060\u307b\u3094\u308b\u3073\u3090\u305a\u307a\u3084\u3082\u3095\u306e\u3085\u3041\u304c\u3055\u305e\u3043\u3060\u3096\u3077\u3060\u3079\u3084\u304d\u308f\u3071\u305e\u3049\u306d\n00007 \u3051\u305b\u3070\u3055\u308f\u305d\u3050\u3045\u3079\u3070\u3054\u3080\u3084\u3050\u308d\u3047\u306b\u306a\u305d\u3057\u307e\u3092\u305a\u307d\u305a\u3069\u3079\u308b\u3071\u3043\u304d\u3076\n00008 \u3060\u3096\u308f\u3083\u3095\u3093\u307e\u3045\u3088\u3094\u3089\u307f\u305e\u3062\u306e\u3076\u3079\u3043\u3096\u306d\u306c\u3090\u3074\u307b\u304f\u3070\u3073\u3077\u3081\u3081\u3085\u307a\n00009 \u3077\u3059\u3051\u3047\u304b\u3079\u306c\u3057\u3061\u3050\u304c\u3044\u3066\u306c\u3095\u3081\u308d\u306c\u308a\u3045\u3047\u3072\u3078\u3095\u3084\u304f\u3078\u3062\u304f\u3095\u3053\u3059\n$ newressu --kat\n00000 \u30c5\u30a1\u30cc\u30ea\u30d6\u30a2\u30b9\u30f7\u30d5\u30d8\u30b1\u30f0\u30cd\u30fd\u30f7\u30d6\u30fa\u30ef\u30ea\u30d9\u30c4\u30a4\u30c8\u30bb\u30c3\u30ec\u30da\u30f2\u30be\u30c1\u30f2\u30a7\n00001 \u30e5\u30cf\u30b0\u30eb\u30db\u30de\u30c9\u30bc\u30fc\u30b5\u30f6\u30f6\u30fd\u30c6\u30d7\u30e6\u30b1\u30f1\u30f4\u30d5\u30db\u30b4\u30e8\u30e7\u30b2\u30fa\u30c6\u30b0\u30fc\u30c9\u30b2\u30ac\n00002 \u30e8\u30b0\u30da\u30d6\u30fa\u30d1\u30cb\u30b8\u30c5\u30d8\u30eb\u30ad\u30a5\u30ea\u30a4\u30be\u30ef\u30f3\u30ad\u30aa\u30ad\u30b8\u30e7\u30d1\u30b2\u30da\u30dc\u30d2\u30a0\u30ed\u30e8\u30d4\n00003 \u30ff\u30a3\u30d9\u30b3\u30bb\u30c0\u30ce\u30c6\u30c0\u30dd\u30e8\u30f4\u30d5\u30f5\u30c5\u30ba\u30e4\u30fc\u30b9\u30d8\u30fc\u30e8\u30fc\u30ad\u30e8\u30c4\u30e3\u30f1\u30aa\u30c0\u30a0\u30d5\n00004 \u30f1\u30ab\u30cf\u30e1\u30ca\u30e0\u30c4\u30ea\u30d3\u30f8\u30f9\u30ad\u30ab\u30f3\u30ca\u30c0\u30a8\u30aa\u30f1\u30ba\u30c5\u30e2\u30c6\u30de\u30aa\u30b6\u30c4\u30ee\u30bc\u30ec\u30b8\u30d1\n00005 \u30e7\u30a8\u30ad\u30f7\u30bb\u30da\u30ff\u30a0\u30b2\u30d2\u30ab\u30df\u30e1\u30fa\u30f0\u30ce\u30ac\u30d5\u30ad\u30fd\u30fc\u30ca\u30ba\u30b0\u30ab\u30d7\u30a0\u30aa\u30cd\u30ab\u30da\u30cd\n00006 \u30f5\u30ad\u30ab\u30fe\u30aa\u30f3\u30e8\u30bc\u30d9\u30f0\u30e2\u30df\u30dc\u30eb\u30d2\u30d7\u30de\u30c8\u30c6\u30fa\u30e4\u30f0\u30b9\u30c0\u30fa\u30d0\u30d2\u30a3\u30f4\u30ed\u30f7\u30ea\n00007 \u30ef\u30a5\u30c7\u30fd\u30d5\u30fd\u30c0\u30f4\u30e1\u30e6\u30c5\u30de\u30ea\u30e9\u30c5\u30e5\u30d6\u30dc\u30d4\u30a2\u30de\u30b2\u30b3\u30fa\u30bb\u30a1\u30cd\u30b9\u30f4\u30e2\u30c2\u30ef\n00008 \u30f3\u30cb\u30d0\u30ef\u30f9\u30e6\u30e8\u30e6\u30d9\u30c2\u30ca\u30c4\u30de\u30c5\u30d7\u30d7\u30d4\u30df\u30ad\u30a6\u30f6\u30f8\u30ce\u30c8\u30e1\u30d6\u30f0\u30ee\u30b5\u30da\u30a2\u30ba\n00009 \u30a0\u30a4\u30f6\u30e2\u30a0\u30e9\u30c5\u30db\u30e0\u30c4\u30c1\u30ac\u30bd\u30db\u30dd\u30e1\u30b9\u30c2\u30c9\u30cf\u30c8\u30e9\u30d0\u30e9\u30a0\u30b3\u30ea\u30a3\u30e7\u30cd\u30a2\u30ea\n$ newressu --kan\n00000 \u8cf5\u5ab5\u773c\u7519\u5010\u8cd4\u6b4c\u660e\u5363\u9f1c\u85d5\u558d\u54bd\u5616\u9ce8\u70c9\u92fa\u4e01\u98e7\u5dce\u6a23\u6362\u51c8\u8a4b\u7b43\u802b\u540b\u6600\u6c53\u83c2\u5d6b\u5a3b\n00001 \u94bc\u4ed2\u76dc\u6943\u7984\u6228\u53ca\u8025\u6e42\u5faa\u503e\u6a9f\u5905\u8621\u69b8\u4f86\u9722\u716f\u6def\u72aa\u7958\u560f\u5f68\u843e\u7c32\u7650\u4eae\u9a58\u664f\u799c\u7133\u5587\n00002 \u91ff\u7e10\u93c4\u8ce2\u5d20\u5911\u8197\u9048\u6786\u500d\u6915\u4e57\u7473\u9082\u7089\u7cf2\u8d20\u505c\u6ac3\u59f5\u9139\u58b1\u6f31\u5cb7\u9568\u9c20\u99f2\u555d\u58e2\u5c4c\u5378\u7758\n00003 \u88c2\u68b6\u5a1c\u5955\u767b\u92b4\u6e8f\u7f85\u9ed8\u7971\u5d77\u7420\u729b\u52ad\u7065\u9c08\u9eb8\u99c2\u5915\u8042\u5258\u8708\u9f7e\u53d6\u58fb\u94ec\u5c22\u550b\u7973\u84ff\u7342\u5b40\n00004 \u592e\u9569\u585b\u954b\u8581\u89f5\u4fe9\u8e58\u69a3\u6e83\u8431\u5a56\u6ce0\u73ce\u6b1d\u79d3\u5488\u600b\u90c3\u6e77\u6458\u7be1\u7df9\u6951\u7bd1\u9092\u6fdd\u5043\u7786\u806c\u7da3\u9951\n00005 \u77dd\u9fbc\u648e\u756e\u9faf\u5f89\u60d6\u5d5c\u9d15\u93ae\u7c8e\u9500\u6522\u7163\u7c71\u6c1b\u63ee\u8a91\u7b63\u62ae\u6bac\u6e15\u52ce\u9853\u7264\u8c60\u8ab2\u81b5\u7de3\u528e\u95dd\u9f6e\n00006 \u620f\u5341\u8afb\u528a\u58f4\u9280\u9618\u8aa5\u95c4\u5421\u583c\u7fb7\u7c52\u7699\u9cbb\u8e11\u4f51\u8e8d\u659b\u761b\u65d3\u993a\u8318\u9af3\u4f55\u8423\u618a\u9c43\u795c\u6791\u6420\u5826\n00007 \u8163\u95c2\u5abf\u8f8f\u5dce\u9fd8\u68b6\u9322\u8936\u75c8\u5595\u76e1\u518d\u54ff\u5280\u7cb8\u5e50\u8c5e\u6e49\u567b\u9acf\u615c\u6dcd\u5b33\u578e\u5587\u9a7e\u94d5\u7060\u5a7f\u5ead\u59d1\n00008 \u7b4e\u780f\u7d3b\u516e\u772e\u65cb\u8d40\u7aa4\u869f\u819e\u9711\u550a\u9c99\u9400\u9112\u88b4\u6a46\u7899\u5c85\u995b\u8009\u792e\u61b4\u5a72\u5048\u9a5e\u7ac7\u9c09\u6643\u9c43\u9558\u5d52\n00009 \u511a\u6e7e\u57c8\u52be\u91bd\u838b\u764e\u9c84\u6599\u504c\u5364\u5d79\u65b5\u6db7\u84ac\u4ed3\u774f\u548b\u973f\u9cba\u57fd\u9a98\u9716\u75f0\u9a5e\u600a\u9f9c\u521a\u9783\u70b7\u7b58\u880a\n<\/code><\/pre>\n\n\n\n<p>Mallituloste kiinan satunnaisista merkeist\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ newressu --cn\n00000 \u56a1\u62ea\u5e0e\u9413\u8431\u6f5e\u6ba3\u50d3\u95da\u9090\u9238\u858f\u9053\u9d33\u9787\u8be1\u6259\u8fca\u5cd0\u5f27\u6390\u9f80\u958f\u7f0b\u75d7\u5c1b\u5f26\u5f91\u53ee\u6e43\u90cf\u73ae\n00001 \u7912\u7624\u965f\u90ed\u8476\u931e\u7e08\u4e7a\u54c7\u80a5\u88f2\u86eb\u64bc\u5c94\u8193\u5620\u5711\u69a4\u761d\u711f\u8345\u5c5b\u5f70\u6aba\u656f\u9cf6\u8dc5\u7d8a\u8d67\u8750\u4f00\u92f4\n00002 \u618a\u8f7a\u6415\u9068\u5adf\u6444\u8ba2\u7d10\u4fe2\u5c49\u9012\u89b5\u800e\u688d\u660a\u9c85\u7c7b\u5507\u6f6a\u697a\u7ac5\u76a8\u9f10\u7e6f\u6d9c\u7633\u55a1\u724a\u677f\u979f\u5d5d\u9721\n00003 \u7da0\u6eb2\u9a10\u6c1c\u682f\u60db\u66aa\u572b\u8724\u65bd\u5ff8\u72b1\u96d4\u8075\u6b92\u9660\u891f\u5e04\u5bed\u5702\u60db\u60d3\u7d7e\u86c1\u6eb8\u6274\u757a\u73d8\u6db5\u7af0\u667a\u51b8\n00004 \u7e00\u7e82\u9f5c\u5700\u7478\u8797\u8aee\u6186\u603c\u6603\u7a90\u7425\u6a7a\u7aca\u845d\u9cb4\u5667\u98de\u8b52\u8783\u74e4\u72f6\u96f7\u7b2d\u64a5\u8296\u6733\u5310\u691b\u7241\u5e18\u5610\n00005 \u934e\u70e7\u6fb9\u8663\u581b\u50bd\u9d99\u89a6\u60e7\u58cc\u55d4\u6f4f\u7af2\u897c\u531a\u7bf2\u53fc\u4e1e\u7715\u5b90\u4f30\u7e0d\u98e9\u5c99\u9027\u962d\u86f5\u5382\u590d\u8b72\u534c\u79ac\n00006 \u855c\u9768\u741d\u763b\u9510\u6b74\u9358\u6f83\u5365\u5b34\u9e15\u5125\u8410\u5b1e\u5143\u918c\u9145\u6a03\u4ec3\u758d\u8d07\u8609\u86bd\u4f38\u8405\u7e62\u636c\u84ed\u8226\u4e82\u91fa\u810a\n00007 \u7b08\u5507\u7e31\u65ee\u8eda\u5c54\u6d73\u4f99\u5c94\u8d45\u5c64\u9d14\u8267\u54b4\u8227\u72ac\u71e9\u6123\u7dc6\u910e\u60ad\u5393\u5471\u77b6\u5349\u50ae\u65a0\u5498\u92ea\u9194\u97d4\u9036\n00008 \u767a\u9810\u7f39\u9cfb\u6b85\u76a8\u6366\u5f34\u7dd6\u61f9\u7e3d\u6248\u9c9c\u740f\u4e3a\u50b8\u69df\u8d29\u53a0\u5607\u68bd\u5736\u4e63\u5edd\u7cf0\u5575\u6bcb\u92e3\u4eb7\u665f\u72b2\u8736\n00009 \u7f79\u624d\u795b\u67db\u6893\u7f3e\u773b\u95d2\u841b\u94ff\u5434\u6c16\u680d\u8ef7\u6de1\u7ee3\u88d5\u55e1\u88c5\u6069\u59fe\u70c1\u5cf8\u9389\u91aa\u51b0\u5477\u737d\u4e81\u570a\u63a8\u6e2b<\/code><\/pre>\n\n\n\n<p>Mallituloste korean satunnaisista merkeist\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ newressu --kor\n00000 \uc5c1\ucd66\ubbe5\uc51d\ub269\ud15d\uc5a8\ucca8\ub2ad\ubd76\uc5a5\ubcb6\ub6b7\ud79b\uc7c3\uc236\ucafa\uc744\ud5b8\ud5d4\uc9b9\uc94d\ub294\ub4af\ubb12\ubc3c\ubb27\uc6f3\uba22\ubdf6\uad8b\uc42b\n00001 \uaef1\ucb21\uc4d8\uc1f2\uca2d\ucff5\ub9cf\uc6b1\uc121\ud529\ub561\ud22f\uc733\ub1b4\uaecd\uae97\ud60d\uc074\ud6a2\ud278\uc6cc\uae3b\ud70a\uc305\ub3b7\ub839\uad7c\ud05f\ub68f\uc675\uccdc\uc585\n00002 \ub665\ub1b1\ud286\ub8b7\uc84b\ub938\uad01\ubac1\ubb56\uc652\ud69c\ubd8d\uca79\uaf47\ud010\ubb11\ucfb5\ub416\uccf5\ubb52\ubdbd\ucf5e\ub31f\uba30\ucdf8\uac1c\uc477\ud5bd\ucfc5\ucacd\ucf39\uca37\n00003 \ub925\ud189\ucdd2\ub6aa\uca27\ud789\ub2b8\uaca8\ub889\ub824\uccf5\ubfe0\ucd66\ud1a9\uc999\uc2a4\uc53a\uae98\ub471\ucfac\uc48e\uae43\ub4bb\ub8bc\ucee2\ub9b4\ubc1b\ud2af\ub380\uc7a2\uae62\uacde\n00004 \ucca0\ub269\ub7aa\uc635\uafb2\ucdd6\uc878\uc2ae\ube61\uadd5\ud732\ud20b\ubc7f\ub7df\uae65\uccce\ud6a3\ub1c2\uc02d\ub131\uca4c\ub679\ubd50\uad4a\ube1e\ud3ae\ud644\ubdde\ud02c\ubff4\ube58\ud0d9\n00005 \uac30\uc699\ub04e\uc095\ucd5f\ud046\ubca2\ud61b\uc4e3\uce05\ubd36\uca07\uae43\uc706\ucc1c\ub14a\ud727\uc163\uc90b\ucb7b\ud420\ud65c\ucc26\ubaae\ub9e9\uc50a\ube60\ud44f\ubfce\ub314\uad13\uc62c\n00006 \ud1a9\uc8b8\ub068\uae91\ub60f\ud0e2\uc986\ub939\ubebf\ub195\uae0c\uca01\uc617\ucb6c\ubbdc\ud703\uba6c\uc96a\uba05\ubcc2\ud5d8\ub125\uc3b4\ud78b\uca2b\ucdb1\ub824\uc76a\uac45\ub024\ud34f\ud4e6\n00007 \ub98f\ub8b2\ub94b\ucbc1\ubf34\ud1e7\ud2e9\uce5f\ubbd4\uc977\ud435\uc17e\ub040\ud79d\ud047\uc863\ubfe9\uac82\ubb73\uc085\ub6c0\uc0fa\ud505\ucf91\ub9ab\ub35e\uadca\uc6f2\ube46\ub6de\ud127\ubaff\n00008 \uae0c\ub8fc\ud334\uc56e\ucbe0\ub20d\uc172\uc42a\uc1d0\uca0b\ud694\ubab0\uca5d\uc472\ubec6\ubc2a\uc651\uc375\ub2ba\uc178\ubfc1\ub9bf\ubdf9\ud21a\uc576\ub016\ud557\ub2ac\ub1a8\ucda7\ub7a4\ud36f\n00009 \uc504\ucbbd\uc21f\ud1cd\ub70b\uc776\ud094\uc6ec\ubaa9\ubefd\uc7eb\uc14e\uc45e\ub1eb\ud5e4\ube6d\uc5f6\uc900\uacc6\ub82d\ucc14\ud0cb\ucc9f\ucca9\ud4e7\ubec8\uca23\ud57d\ub9f1\uca05\uc091\ud4f5<\/code><\/pre>\n\n\n\n<p>Edellisten apuohjelmat: digits_add_string() lis\u00e4\u00e4 merkkijonon digits merkkijonoon. digits_add_limits() lis\u00e4\u00e4 utf8 merkkiv\u00e4lin digits merkkijonoon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG55 2\n\nvoid digits_add_string(unsigned char **digits, char *str)\n{\n  int digitssize;\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\",*digits);\n  fprintf(stdout,\"\\nadddigits %s\",str);\n#endif\n  digitssize=0;\n  if(*digits!=NULL)\n    digitssize+=strlen(*digits);\n  digitssize+=strlen(str);\n  *digits=realloc(*digits,digitssize+1);\n  strcat(*digits,str);\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\",*digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nvoid digits_add_limits(unsigned char **digits, int start, int end)\n{\n  int c, digitssize;\n  unsigned char buffer&#91;10];\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\",*digits);\n  fprintf(stdout,\"\\nadddigits start:%d, end:%d\",start,end);\n#endif\n  digitssize=0;\n  if(*digits!=NULL)\n    digitssize+=strlen(*digits);\n  \n  for(c=start;c&lt;=end;c++) {\n    codetoutf8(buffer,c);\n    digitssize+=strlen(buffer);\n  }\n  *digits=realloc(*digits,digitssize+1);\n  for(c=start;c&lt;=end;c++) {\n    codetoutf8(buffer,c);\n    strcat(*digits,buffer);\n  }\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\",*digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Ja apuohjelmien apuohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG42 2\n\nstatic void codetoutf8(unsigned char *buf2, unsigned long code)\n{\n  unsigned char *buf;\n\n  buf=buf2;\n  if(code&lt;=0x7f) {\n    *buf++=code;\n  } else if(code&lt;=0x7ff) {\n    *buf++=(0xc0 | ((code&gt;&gt;6)&amp;0x1f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0xffff) {\n    *buf++=(0xe0 | ((code&gt;&gt;12)&amp;0x0f));\n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0x10ffff) {\n    *buf++=(0xf0 | ((code&gt;&gt;18)&amp;0x07));\n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffff) { \/\/ these not yet needed\n    *buf++=(0xf8 | ((code&gt;&gt;24)&amp;0x03));\n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x7fffffff) { \/\/ these not yet needed\n    *buf++=(0xfc | ((code&gt;&gt;30)&amp;0x01));\n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0xfffffffff) { \/\/ these not yet needed\n    *buf++=(0xfe);\n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffffffff) { \/\/ these not yet needed\n    *buf++=(0xff);\n    *buf++=(0x80 | ((code&gt;&gt;36)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  }\n  *buf='\\0';\n\n#ifdef DEBUG42\n  int c;\n\n  fprintf(stdout,\"codepoint: %11lx, utf8: \",code);\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\"%02x\",buf2&#91;c]);\n  }\n  fprintf(stdout,\",\");\n  for(;c&lt;8;c++) {\n    fprintf(stdout,\"  \");\n  }\n  fprintf(stdout,\" utf8bin: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    for(int d=7;d&gt;=0;d--)\n      fprintf(stdout,\"%d\",buf2&#91;c]&gt;&gt;d&amp;1);\n  }\n  fprintf(stdout,\",\");\n  for(;c&lt;8;c++) {\n    fprintf(stdout,\"        \");\n  }\n  fprintf(stdout,\" character: %s\",buf2);\n  fprintf(stdout,\"\\n\");\n#endif\n}<\/code><\/pre>\n\n\n\n<p>DEBUG42 tulostaa t\u00e4ll\u00e4isen infon konvertoidessaan kokonaislukuja utf8 merkkijonoiksi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>codepoint:        735e, utf8: e78d9e,           utf8bin: 111001111000110110011110,                                         character: \u735e\ncodepoint:        735f, utf8: e78d9f,           utf8bin: 111001111000110110011111,                                         character: \u735f\ncodepoint:        7360, utf8: e78da0,           utf8bin: 111001111000110110100000,                                         character: \u7360\ncodepoint:        7361, utf8: e78da1,           utf8bin: 111001111000110110100001,                                         character: \u7361\ncodepoint:        7362, utf8: e78da2,           utf8bin: 111001111000110110100010,                                         character: \u7362\ncodepoint:        7363, utf8: e78da3,           utf8bin: 111001111000110110100011,                                         character: \u7363\ncodepoint:        7364, utf8: e78da4,           utf8bin: 111001111000110110100100,                                         character: \u7364\ncodepoint:        7365, utf8: e78da5,           utf8bin: 111001111000110110100101,                                         character: \u7365\ncodepoint:        7366, utf8: e78da6,           utf8bin: 111001111000110110100110,                                         character: \u7366\ncodepoint:        7367, utf8: e78da7,           utf8bin: 111001111000110110100111,                                         character: \u7367\n<\/code><\/pre>\n\n\n\n<p>Seuraavalla newressu:n &#8211;timer kytkimell\u00e4 voidaan tulostaa raporttirivi komennon suoritusajasta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/newressu --timer\n00000 14201844240371822100253951836708816138416704547327938279020612823\n00001 96317707705252111732289508490822470980426867566840559420270289362\n00002 00689262243741247223559402961899678231026820771707893001586218306\n00003 58979497167864424785641519129614693821588197298234540350089230127\n00004 79789151626389687113003359838448204303247463484081137703428742320\n00005 11646624843275547205294740326170331083195859451166500230279215257\n00006 73962496095430961154950496584940973872290305555433845726378885241\n00007 50019973396634088019938782699506630602624836322165073299771817377\n00008 45442780578169763986650183569757727708029002163610361259691700882\n00009 66002136323947761070898295750362946156839041366424942241622661094\nrun time 0.010476 seconds, 10 lines, 1059.484482 useconds\/line, 65 characters\/line, 16.308931 useconds\/character<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef USE_TIMER\n      } else if(!strcmp(\"--timer\",argv&#91;c])) {\n        timer=1;\n#endif<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef USE_TIMER\n  timerstart=getseconds();\n#endif<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef USE_TIMER\n  if(timer) {\n    double timertook=getseconds()-timerstart;\n    fprintf(stdout,\"run time %f seconds\",timertook);\n    fprintf(stdout,\", %lld lines\",plines);\n    fprintf(stdout,\", %f useconds\/line\",timertook*1000000\/plines);\n    fprintf(stdout,\", %d characters\/line\",pwords*size);\n    fprintf(stdout,\", %f useconds\/character\",(timertook*1000000\/plines)\/(pwords*size));\n    fprintf(stdout,\"\\n\");\n   }\n#endif<\/code><\/pre>\n\n\n\n<p>Korjattu lokien kirjoitus siten ett\u00e4 vain yksi prosessi voi kirjoittaa niit\u00e4 kerrallaan. T\u00e4ss\u00e4 se on toteutettu semaphore:illa. Aluksi https-palvelin, johon on lis\u00e4tty kutsut semaphore funktioille: Funktion alussa poistetaan vanha semaphore sem_unlink() kutsulla. Sen j\u00e4lkeen avataan uusi sem_open() kutsulla. Vuoroa odotetaan sem_wait() kutsulla. Semaphore vapautetaan seuraavalle k\u00e4ytt\u00e4j\u00e4lle sem_post() kutsulla. Semaphore:t poistetaan lopuksi sem_unlink ja sem_close komennoilla.<\/p>\n\n\n\n<p>Lis\u00e4ksi https_server() funktiosta on ulkoistettu tavalliset socket kutsut (getaddrinfo(), server_socket(), server_bind(), freeaddrinfo() ja server_listen()) funktioon server_basic_socket(). Https palvelimesta ulkoistetut funktiot (SSL_library_init(), OpenSSL_add_ssl_algorithms(), OpenSSL_add_ciphers(), OpenSSL_load_error_strings(), SSLv23_server_method(), SSL_CTX_new(), SSL_CTX_use_certificate_file(), SSL_CTX_use_PrivateKey_file() ja SSL_CTX_load_verify_locations()) on sijoitettu funktioon server_https_init(). Ohjelmassa on samat rivit samassa j\u00e4rjestyksess\u00e4, niit\u00e4 on vain v\u00e4h\u00e4n siirrelty.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG59 2\n#define DEBUG81 2\n\nstatic void https_server()\n{\n  int quit, reset, addr_size;\n  \n  \/\/SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n\n  struct sockaddr_in sa_cli;\n\n  signal(SIGPIPE, SIG_IGN);\n  signal(SIGCHLD, SIG_IGN);\n\n#ifdef USE_SEMAPHORES\n\n  unsigned char semname&#91;32];\n  sem_t *mutex;\n\n  sprintf(semname,\"dbssem%s\",myport);\n\n  if(sem_unlink(semname)==0) {\n    fprintf(stdout,\"%s: previous semaphore %s removed\\n\",procname,semname);\n  }\n  mutex=sem_open(semname, O_CREAT | O_EXCL, 0644, 1);\n\n#endif\n\n  \/\/ plus space for '\\0'  \n  htmlin = malloc(htmlinlen+1);\n    \n  reset=1;\n  quit=0;\n  \n  for(;;) {\n\n    if(quit) {\n      if(ctx!=NULL)\n\tSSL_CTX_free(ctx);\n      break;\n    }\n    if(reset) {\n      if(ctx!=NULL) {\n#ifdef DEBUG42\n\tfprintf(stdout,\"SSL_CTX_free()\\n\");\n#endif\n\tSSL_CTX_free(ctx);  \n      }\n\n      ctx=server_https_init();\n      s=server_basic_socket();\n\n      reset=0;\n    } \/\/ if(reset)\n\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n    \n    addr_size = sizeof(sa_cli);\n#ifdef DEBUG42\n    fprintf(stdout,\"accept()\\n\");\n#endif\n    if((news=accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size))==-1) {\n      fprintf(stderr,\"\\n%s: cannot accept()\\n\", procname);\n      perror(\"accept\");\n    }\n\n    if(beepaccept) {\n      fprintf(stderr,\"\\a\");\n      fflush(stderr);\n    }\n\n    pid_t pid;\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork start (parent)\");\n    fprintf(stdout,\" getpid:%d getppid:%d\",getpid(),getppid()); \n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n    if((pid=fork())&lt;0) {\n#ifdef USE_SEMAPHORES\n      sem_unlink(semname);\n      sem_close(mutex);\n#endif\n      fprintf(stderr,\"\\n%s: cannot fork()\\n\", procname);\n      perror(\"fork\");\n    }\n    if(pid==0) {\n      log_clear();\n      log_printf(\"==========\\n\");\n#ifdef DEBUG59\n      fprintf(stdout,\"Fork start (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      close(s);\n\n      https_client(news,ctx,sa_cli,addr_size,\"https\");\n\n#ifdef DEBUG81\n      fprintf(stdout,\"%s\",logbuf);\n      fflush(stdout);\n      log_clear();\n#endif\n\n#ifdef USE_SEMAPHORES\n      \n      fprintf(stdout,\"locking semaphore(child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n      \n      if(sem_wait(mutex)==-1) {\n\tfprintf(stderr, \"%s: cannot sem_wait(), error: %d\\n\", procname, errno);\n\tperror(\"sem_wait\");\n      }\n      \n      fprintf(stdout,\"critical section (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      \n      dbs_run_critical();\n\n#ifdef USE_SEMAPHORES\n      \n      fprintf(stdout,\"end critical section (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n\n      if(sem_post(mutex)==-1) {\n\tfprintf(stderr, \"%s: cannot sem_post(), error: %d\\n\", procname, errno);\n\tperror(\"sem_post\");\n      }\n\n      fprintf(stdout,\"release semaphore(child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n      \n#endif\n      \n      server_close(news);\n      fprintf(stdout,\"%s\",logbuf);\n      fflush(stdout);\n      log_clear();\n      \n#ifdef DEBUG59\n      fprintf(stdout,\"Fork end (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      exit(0);\n    }\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork end (parent)\");\n    fprintf(stdout,\" pid:%d getpid:%d getppid:%d\",pid,getpid(),getppid());\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n  } \/\/ for(;;)\n  SSL_CTX_free(ctx);  \n\n#ifdef USE_SEMAPHORES\n  sem_unlink(semname);\n  sem_close(mutex);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Seuraavaksi server_basic_socket() funktio:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int server_basic_socket()\n{\n  int s;\n  struct addrinfo *res;\n\n  server_getaddrinfo(myport,&amp;res);\n  s = server_socket(res);\n  server_bind(s,res);\n  freeaddrinfo(res);\n  server_listen(s);\n\n  return(s);\n}<\/code><\/pre>\n\n\n\n<p>Sitten server_https_init():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static SSL_CTX *server_https_init()\n{\n  SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_library_init()\\n\");\n#endif\n  SSL_library_init();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_add_ssl_algorithms()\\n\");\n#endif\n  OpenSSL_add_ssl_algorithms();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_add_ciphers()\\n\");\n#endif\n  OpenSSL_add_all_ciphers();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_load_error_strings()\\n\");\n#endif\n  SSL_load_error_strings();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSLv23_server_method()\\n\");\n#endif\n  if((method = (SSL_METHOD *)    \n      SSLv23_server_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\\n\", procname);\n    \/\/fflush(stderr);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_new()\\n\");\n#endif\n  if((ctx=SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\\n\", procname);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_use_certificate_file()\\n\");\n#endif\n  if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) &lt;= 0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\\n\", procname);\n    fflush(stderr);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_use_PrivateKey_file()\\n\");\n#endif\n  if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM)&lt;=0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\\n\", procname);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_load_verify_locations()\\n\");\n#endif\n  if(!SSL_CTX_load_verify_locations(ctx, cert_file, NULL)) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_verify_locations()\\n\", procname);\n  }\n  return(ctx);\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 viel\u00e4 tuo vuoroja tarvitseva rutiini:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void dbs_run_critical()\n{\n  FILE *fp1;\n  char filename&#91;128];\n  char filename2&#91;128];\n\n  sprintf(filename,\"%stimelog.deb\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  if((fp1=fopen(filename,\"a\"))!=NULL) {\n    fprintf(fp1,\"%s, ip=\\\"%s\\\"\\n\",htmltimeshort, htmlip);\n    fclose(fp1);\n  }\n  \n  sprintf(filename,\"%sips.deb\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  dbs_add_end_new_str(filename, htmlip);\n\n  sprintf(filename,\"%shostname.deb\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  dbs_add_end_new_str(filename, htmlhostname);\n\n  if(htmlsslcipher&#91;0]!='\\0') {\n    sprintf(filename,\"%sciphers.deb\",filenamehead);\n#ifdef DEBUG34\n    fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n    dbs_add_end_new_str(filename,htmlsslcipher);\n  }\n\n  fprintf(stdout,\"Fetching User-Agent\\n\");\n  unsigned char *p,buffer&#91;1024];\n  if((p=dbs_html_get_request_line(\"User-Agent\",sizeof(buffer),buffer))!=NULL) {\n#ifdef DEBUG35\n    fprintf(stdout,\"fetch User-Agent: \\\"%s\\\"\\n\",p);\n#endif\n    sprintf(filename,\"%suseragent.deb\",filenamehead);\n#ifdef DEBUG34\n    fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n    dbs_add_end_new_str(filename,buffer);\n  }\n\n  sprintf(filename2,\"%scallid.deb\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Reading %s\\n\",filename2);\n#endif\n  if((fp1=fopen(filename2,\"r\"))!=NULL) {\n    unsigned char buffer16&#91;16];\n    fgets(buffer16,sizeof(buffer16),fp1);\n    callid=atoi(buffer16);\n    fclose(fp1);\n  }\n  log_printf(\"callid:%d\\n\",callid);\n  sprintf(filename,\"%shtml.deb\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  if((fp1 = fopen(filename,\"a\")) != NULL) {\n    fprintf(fp1,\"htmltime: \\\"%s\\\", htmltimeshort: \\\"%s\\\", ip=\\\"%s\\\", callid=\\\"%d\\\"\\n\",htmltime, htmltimeshort, htmlip, callid);\n    fprintf(fp1,\"%s\\n\",htmlin);\n    for(int c=0;c&lt;HTML_BUFFERS;c++) {\n#ifdef DEBUG31\n      fprintf(stdout,\"%d\",c);\n      fprintf(stdout,\" %p\",html_get_string(c));\n      if(html_get_string(c)!=NULL)\n\tfprintf(stdout,\"%s\",html_get_string(c));\n#endif\n      if(html_get_string(c)!=NULL &amp;&amp;\n\t strlen(html_get_string(c))&gt;0) {\n\tfprintf(fp1,\"%d: %s\\n\",c,html_get_string(c));\n      }\n    }\n    fclose(fp1);\n  }\n  \n  callid++; \/\/ next call id\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename2);\n#endif\n  if((fp1=fopen(filename2,\"w\"))!=NULL) {\n    fprintf(fp1,\"%d\\n\",callid);\n    fclose(fp1);\n  }\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4tty terttu henkinen yhteinen loki palvelimille: aluksi mallitietue lokista: (rullaa oikealle) Tietueen lopussa uudet kent\u00e4t useconds ja prevminutes, joista ensimm\u00e4inen kertoo asiakkaan prosessin viem\u00e4n ajan ja toinen viimeisten kutsujen m\u00e4\u00e4r\u00e4n. N\u00e4it\u00e4 tarkkailemalla on tarkoituksena l\u00f6yt\u00e4\u00e4 raja, jolla palvelin ei voi en\u00e4\u00e4 suoriutua ja poistaa asiakkaan t\u00f6it\u00e4 (t\u00e4ss\u00e4 satunnaislukujen muodostus+tulostus). T\u00e4ss\u00e4 voidaan muuttaa sivusis\u00e4lt\u00f6 johonkin palvelin on nyt ruuhkaantunut tekstiin ja j\u00e4tt\u00e4\u00e4 asiakkaan t\u00f6ist\u00e4 osa pois.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'procname' = \".\/dbs\", 'timeshort' = \"EET20220317002226\", 'time' = \"Thu, 17 Mar 2022 00:22:26 EET\", 'host' = \"1.2.3.4:5006\", 'hostname' = \"1.2.3.4\", 'useragent' = \"\", 'method' = \"GET\", 'path' = \"\/\", 'version' = \"HTTP\/1.1\", 'filename' = \"\", 'fileextension' = \"\", 'cookie' = \"\", 'sessionid' = \"\", 'params' = \"\", 'digest' = \"aaaabbbbccccdddd\", 'mode' = \"\", 'ip' = \"1.2.3.4\", 'sslcipher' = \"TLS_AES_128_GCM_SHA256\", 'port' = \"10227\", 'language' = \"fi\", 'useconds' = \"118438\", 'prevminutes' = \"2 2 1 0 0 0 0 0 0 0 0 0 0 0 0\"<\/code><\/pre>\n\n\n\n<p>Sitten lokin tarvitsema tietorakenne:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>struct lfield {\n  unsigned char *name;\n  int valuetype;\n  unsigned char *value;\n  int size;\n} lfields&#91;] = {\n  { \"procname\", 1, (unsigned char *)&amp;procname, 32 },\n  { \"timeshort\", 0, htmltimeshort, sizeof(htmltimeshort) },\n  { \"time\", 0, htmltime, sizeof(htmltime) },\n  { \"host\", 0, htmlhost, sizeof(htmlhost) },\n  { \"hostname\", 0, htmlhostname, sizeof(htmlhostname) },\n  { \"useragent\", 0, htmluseragent, sizeof(htmluseragent) },\n  { \"method\", 0, htmlmethod, sizeof(htmlmethod) },\n  { \"path\", 0, htmlpath, sizeof(htmlpath) },\n  { \"version\", 0, htmlversion, sizeof(htmlversion) },\n  { \"filename\", 0, htmlfilename, sizeof(htmlfilename) },\n  { \"fileextension\", 0, htmlfileextension, sizeof(htmlfileextension) },\n  { \"cookie\", 0, htmlcookie, sizeof(htmlcookie) },\n  { \"sessionid\", 0, htmlsessionid, sizeof(htmlsessionid) },\n  { \"params\", 1, (unsigned char *)&amp;htmlparams, 0 },\n  { \"digest\", 0, htmldigest, sizeof(htmldigest) },\n  { \"mode\", 0, htmlmode, sizeof(htmlmode) },\n  { \"ip\", 0, htmlip, sizeof(htmlip) },\n  { \"sslcipher\", 0, htmlsslcipher, sizeof(htmlsslcipher) },\n  { \"port\", 0, htmlport, sizeof(htmlport) },\n  { \"language\", 0, htmllanguage, sizeof(htmllanguage) },\n  { \"useconds\", 0, htmluseconds, sizeof(htmluseconds) },\n  { \"prevminutes\", 0, htmlprevminutes, sizeof(htmlprevminutes) },\n};<\/code><\/pre>\n\n\n\n<p>Kent\u00e4n tulostusrutiini: saa puskurin osoitteen ja vapaan tilan puskurissa. Jos kent\u00e4n nimi ja arvo pari mahtuu puskuriin, se tulostetaan sinne. Aina palautetaan nimi arvoparin pituus. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db4_compile_field(int buflength, unsigned char *buf, unsigned char *name)\n{\n  int size=0;\n  unsigned char *value=NULL;\n\n  for(int c=0;c&lt;sizeof(lfields)\/sizeof(struct lfield);c++) {\n    if(!strcmp(name,lfields&#91;c].name)) {\n      if(lfields&#91;c].valuetype==0) {\n\tvalue=lfields&#91;c].value;\n\tbreak;\n      } else if(lfields&#91;c].valuetype==1) {\n\tvalue=*((unsigned char **)lfields&#91;c].value);\n\tbreak;\n      }\n\n    }\n  }\n  size=7+strlen(name);\n  if(value!=NULL)\n    size+=strlen(value);\n  \n  if(size&lt;buflength) {\n    strcat(buf,\"'\");\n    strcat(buf,name);\n    strcat(buf,\"' = \\\"\");\n    if(value!=NULL)\n      strcat(buf,value);\n    strcat(buf,\"\\\"\");\n  }\n  return(size);\n}\n<\/code><\/pre>\n\n\n\n<p>(Loki)rivin tulostusrutiini: Taas sama juttu, tulostetaan mahtuvat kent\u00e4t puskuriin ja palautetaan koko tietueen pituus (ilman &#8216;\\0&#8217; merkki\u00e4) <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int db4_compile_set(int buflen, unsigned char *buf2)\n{\n  int size, count, first=1;\n  unsigned char *buf = buf2;\n  size=0;\n  if(buflen&gt;0)\n    buf&#91;0]='\\0';\n  \n  for(int c=0;c&lt;sizeof(lfields)\/sizeof(struct lfield);c++) {\n    count=0;\n    if(!first) {\n      if(2&lt;buflen)\n\tstrcat(buf,\", \");\n      count+=2;\n    }\n    count+=db4_compile_field(buflen,buf,lfields&#91;c].name);\n    buf+=count;\n    buflen-=count;\n    size+=count;\n    first=0;\n  }\n  \n  return(size);\n}<\/code><\/pre>\n\n\n\n<p>Ja edellist\u00e4 kutsuva p\u00e4tk\u00e4: (jos koko tietue ei mahdu puskuriin suurennetaan puskuria ja yritet\u00e4\u00e4n uudestaan).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define DEBUG39\n\nstatic void dbs_run_critical_all() {\n  int count, buflen=0;\n  unsigned char *buf=NULL;\n\n#ifdef DEBUG39\n  fprintf(stdout,\"db4_compile_set() %d\\n\",buflen);\n  fflush(stdout);\n#endif\n  count=db4_compile_set(buflen,buf)+1;\n    \n  if(buflen&lt;count) {\n    buflen=count;\n    buf=realloc(buf,buflen);\n#ifdef DEBUG39\n    fprintf(stdout,\"db4_compile_set() %d\\n\",buflen);\n    fflush(stdout);\n#endif\n    count=db4_compile_set(buflen,buf)+1;\n  }\n  FILE *fp1;\n  if((fp1 = fopen(\"dbs.skk\",\"a\")) != NULL) {\n    fprintf(fp1,\"%s\\n\",buf);\n    fclose(fp1);\n  }\n  fprintf(stdout,\"%s(%ld)\\n\",buf,strlen(buf));\n  fflush(stdout);\n  \/\/for(int c=0;c&lt;sizeof(lfiles)\/sizeof(struct lfile);c++) {\n  \/\/fprintf(stdout,\"%s\",lfiles&#91;c].filename);\n  \/\/}\n}<\/code><\/pre>\n\n\n\n<p>Korjattu bugi intelrandom.c ohjelman rdseed rutiinissa lis\u00e4\u00e4m\u00e4ll\u00e4 toistoja, jos rdseed ei toimi: (while tries kappale)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int rdseed_bytes(int buflen, unsigned char *buf)\n{\n  int n, ret = 0;\n  unsigned long l;\n\n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdseed()) {\n    if(fort_verbose)\n      fprintf(stdout,\"Intel rdseed\");\n    ret=1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdseed()) {\n    if(fort_verbose)\n      fprintf(stdout,\"AMD rdseed\");\n    ret=1;\n  }\n\n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries=0;\n      while(++tries &lt; 100) {\n\tif((ret = _rdseed_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n      }\n      if(ret==0)\n\tbreak;\n      if(fort_verbose) {\n\tfprintf(stdout,\" %016lx\",l);\n\tnewressu_output=1;\n      }\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n      memcpy(buf, (unsigned char *)&amp;l, n);\n      buf+=n;\n      buflen-=n;\n    }\n  }\n  return(ret);\n}\n<\/code><\/pre>\n\n\n\n<p>Huomasin, ett\u00e4 codepointilla ja muodostetulla utf8 koodilla on yhteys, joka n\u00e4kyy oktaalina: lis\u00e4sin oktaaliversion debug42:n tulostukseen: vertaile oktaalista codepoint:ia ja my\u00f6hemp\u00e4\u00e4 utf8 koodia oktaalina.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>codepoint: 4e03, bin:1001110|00000011, oct:47003, utf8: e4b883, bin: 11100100|10111000|10000011, oct:\n 344 270 203, character: \u4e03\ncodepoint: 4e04, bin:1001110|00000100, oct:47004, utf8: e4b884, bin: 11100100|10111000|10000100, oct:\n 344 270 204, character: \u4e04\n<\/code><\/pre>\n\n\n\n<p>Seuraavassa uusi versio koodista, jossa oktaalikent\u00e4t on lis\u00e4tty ja lis\u00e4ksi debukkirivi muotoiltu uudelleen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG42 2\n\nstatic void codetoutf8(unsigned char *buf2, unsigned long code)\n{\n  unsigned char *buf;\n\n  buf=buf2;\n  if(code&lt;=0x7f) {\n    *buf++=code;\n  } else if(code&lt;=0x7ff) {            \/\/ 110xxxxx 10xxxxxx\n    *buf++=(0xc0 | ((code&gt;&gt;6)&amp;0x1f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0xffff) {           \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n    *buf++=(0xe0 | ((code&gt;&gt;12)&amp;0x0f));\n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0x10ffff) {         \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *buf++=(0xf0 | ((code&gt;&gt;18)&amp;0x07));\n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffff) {        \/\/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xf8 | ((code&gt;&gt;24)&amp;0x03));\n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x7fffffff) {       \/\/ 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xfc | ((code&gt;&gt;30)&amp;0x01));\n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0xfffffffff) {      \/\/ 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xfe);\n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffffffff) {    \/\/ 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xff);\n    *buf++=(0x80 | ((code&gt;&gt;36)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  }\n  *buf='\\0';\n\n#ifdef DEBUG42\n  int c,print;\n\n  fprintf(stdout,\"codepoint: %lx\",code);\n\n  fprintf(stdout,\", bin:\");\n\n  print=0;\n  for(c=(sizeof(code)*8)-1;c&gt;=0;c--) {\n    int bit=(code&gt;&gt;c)&amp;1;\n    if(bit!=0)\n      print=1;\n    if(print) {\n      fprintf(stdout,\"%d\",bit);\n      if(c&gt;0 &amp;&amp; c%8==0)\n\tfprintf(stdout,\"|\");\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  print=0;\n  fprintf(stdout,\"%lo\",code);\n\n  fprintf(stdout,\", utf8: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\"%02x\",buf2&#91;c]);\n  }\n\n  fprintf(stdout,\", bin: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    if(c&gt;0)\n      fprintf(stdout,\"|\");\n    for(int d=7;d&gt;=0;d--) {\n      fprintf(stdout,\"%d\",buf2&#91;c]&gt;&gt;d&amp;1);\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\" %3o\",buf2&#91;c]);\n  }\n  \n  fprintf(stdout,\", character: %s\",buf2);\n  fprintf(stdout,\"\\n\");\n#endif\n}<\/code><\/pre>\n\n\n\n<p>Uudelleen kirjoitettu h\u00e4kkyr\u00e4 ressu_gen_limit(), joka palauttaa annettua rajaa pienemm\u00e4n satunnaisluvun. Aiemmin uuden funktion toiminnon teki useampi funktio. Edellisess\u00e4 oli funktioita ressu_genbyte_limit(), ressu_genshort() ressu_genshort_limit, ressu genint() ja niin edelleen. Uudessa versiossa ne on tiivistetty simppelimp\u00e4\u00e4n muotoon: (vanha koodi on mukana lopun sorsassa #ifdef OLD1 blokissa t\u00e4m\u00e4n uudemman funktion j\u00e4lkeen)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aDEBUG19 2\n#define aDEBUG24 2\n\nunsigned long ressu_gen_limit(unsigned long limit)\n{\n  int c, bytes;\n  unsigned long word, highlimit;\n  \n  if(limit&lt;=0x100) { \/\/ 1 byte\n    highlimit=0x100;\n    bytes=1;\n  } else if(limit&lt;=0x10000) { \/\/ 2 bytes\n    highlimit=0x10000;\n    bytes=2;\n  } else if(limit&lt;=0x1000000) { \/\/ 3 bytes\n    highlimit=0x1000000;\n    bytes=3;\n  } else if(limit&lt;=(unsigned long)0x100000000) { \/\/ 4 bytes\n    highlimit=0x100000000;\n    bytes=4;\n  } else if(limit&lt;=(unsigned long)0x10000000000) { \/\/ 5 bytes\n    highlimit=0x10000000000;\n    bytes=5;\n  } else if(limit&lt;=(unsigned long)0x1000000000000) { \/\/ 6 bytes\n    highlimit=0x1000000000000;\n    bytes=6;\n  } else if(limit&lt;=(unsigned long)0x100000000000000) { \/\/ 7 bytes\n    highlimit=0x100000000000000;\n    bytes=7;\n  } else { \/\/ if(limit&lt;=(unsigned long)0xffffffffffffffff) { \/\/ 8 bytes\n    highlimit=0xffffffffffffffff;\n    bytes=8;\n  }\n\n  for(;;) {\n    word=0;\n    for(c=0;c&lt;bytes;c++)\n      word = word &lt;&lt; 8 | ressu_genbyte();\n    if(word &lt; (highlimit\/limit)*limit)\n      break;\n  }\n\n  word%=limit;\n  \n#ifdef DEBUG24\n  fprintf(stdout,\"\/\");\n#ifdef DEBUG19\n  fprintf(stdout,\"%d bytes: \", bytes);\n#endif\n  if(type==2)\n    fprintf(stdout,\"%lx\", word);\n  else if(type==8)\n    fprintf(stdout,\"%lo\", word);\n  else if(type==10)\n    fprintf(stdout,\"%lu\", word);\n  else if(type==16)\n    fprintf(stdout,\"%lx\", word);\n  else\n    fprintf(stdout,\"%lu\", word);\n  fprintf(stdout,\"\/\");\n  fflush(stdout);\n#endif\n\n  return(word);\n}<\/code><\/pre>\n\n\n\n<p>Lis\u00e4ksi lis\u00e4tty kaksi uutta laskentatapaa ressun ns teoreettisten satunnaisbittien laskentaan: Ensimm\u00e4isess\u00e4 mallissa (rndbits3) eniten ilmestynytt\u00e4 ketjun pituutta pidet\u00e4\u00e4n satunnaisuuden suhteen neutraalina, eli ett\u00e4 se ei sis\u00e4ll\u00e4 yht\u00e4\u00e4n satunnaisuutta. Kaikkien muiden pituiset ketjut lasketaan sis\u00e4lt\u00e4v\u00e4n yhden bitin satunnaisuutta. Toisessa mallissa (rndbits4) pituudeltaan pisimm\u00e4t ketjut lasketaan neutraaleiksi ja niit\u00e4 lyhyemm\u00e4t ketjut sis\u00e4lt\u00e4v\u00e4t yhden bitin satunnaisuutta. Pisimm\u00e4t ketjut voivat olla esimerkiksi ne, joiden esiintymism\u00e4\u00e4r\u00e4 sis\u00e4lt\u00e4\u00e4 nelj\u00e4 numeroa (esimerkiksi 1234, 2222, 3443) ja kolme numeroa tai lyhyemm\u00e4t lasketaan teoreettisiin satunnaisbitteihin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c, d, e, f;\n  static int ressut_first = 1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  unsigned long prevperiods&#91;1024];\n  \n  for(c = 0; c &lt; size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut, 0, ressut_bytes);\n\tressut_first = 0;\n      }\n\n      clockbytes=0;\n      for(d = 0; d &lt; 1024; d++) {\n\tperiods&#91;d] = 0;\n      }\n      \n      rndbits1 = 0;\n      rndbits2 = 0;\n      rndbits3 = 0;\n      rndbits4 = 0;\n\n      int lim, lim1 = 0, lim2 = 0;\n      int lim1a, lim1b;\n      int high1, high2;\n\n      int rndbits3high;\n#ifdef DEBUG6\n      int rndbits4high;\n#endif\n      int rndbits4highdigits;\n      \n      for(d = 0;\n\t  rndbits1 &lt; ressu_bits1_needed ||\n\t  rndbits2 &lt; ressu_bits2_needed ||\n\t  rndbits3 &lt; ressu_bits3_needed ||\n\t  rndbits4 &lt; ressu_bits4_needed ||\n\t  d &lt; RESSU_MIN_ROUNDS ||\n\t    clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n\t\/\/\n\t\/\/  calculate rndbits1\n\t\/\/\n\t\n...\n\n\tressu_genbytes_single(ressut_bytes, ressut);\n...\n\t\/\/\n\t\/\/  calculate rndbits3\n\t\/\/\n\n\trndbits3high=0;\n\trndbits3=0;\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits3high &lt; periods&#91;e])\n\t    rndbits3high = periods&#91;e];\n\t}\n#ifdef DEBUG8\n\tfprintf(stdout,\"\\n%d:\", rndbits3high);\n#endif\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits3high &gt; periods&#91;e]) {\n\t    rndbits3 += periods&#91;e];\n#ifdef DEBUG8\n\t    if(periods&#91;e]&gt;0)\n\t      fprintf(stdout,\" %ld(%d)\", periods&#91;e],rndbits3);\n#endif\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits4\n\t\/\/\n\n\trndbits4highdigits=0;\n#ifdef DEBUG6\n\trndbits4high=0;\n#endif\n\trndbits4=0;\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &lt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4highdigits = (int)log10((double)periods&#91;e]) + 1;\n#ifdef DEBUG6\n\t    rndbits4high = periods&#91;e];\n#endif\n\t  }\n\t}\n#ifdef DEBUG6\n\tfprintf(stdout,\"\\n%d:\", rndbits4high);\n#endif\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &gt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4 += periods&#91;e];\n#ifdef DEBUG6\n\t    if(periods&#91;e]&gt;0)\n\t      fprintf(stdout,\" %ld(%d)\", periods&#91;e],rndbits4);\n#endif\n\t  }\n\t}\n      } \/\/ for(d=0;\n---\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n#ifdef DEBUG7\n  for(c = 0; c &lt; size; c++) {\n    if(c%32 == 0)\n      fprintf(stdout, \"\\ngenbytes  \");\n    fprintf(stdout, \"%02x\", buffer&#91;c]);\n    newressu_output = 1;\n  }\n  fprintf(stdout, \"\\n\");\n#endif\n  \n  genbytes+=size;\n}<\/code><\/pre>\n\n\n\n<p>L\u00e4hdekoodi ressu4 palvelimelle<\/p>\n\n\n\n<p>Makefile<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CC =            cc\nCFLAGS =        -g -Wall -Wno-pointer-sign\nnewressuobjs =  newressu.mfs.o fort.o sha256.o intelrandom.o webrandom.o commandrandom.o\nressu4objs =    ressu4.o html.o dbs.o sha256.o\n\nall:            newressu ressu4\n\nnewressu:       $(newressuobjs)\n                cc $(CFLAGS) $(newressuobjs) -o newressu -lssl -lcrypto -lm\n\nressu4:         $(ressu4objs)\n                cc $(CFLAGS) $(ressu4objs) -pthread -o ressu4 -lssl -lcrypto -lm\n\nsha256:         $(sha256objs)\n                cc $(CFLAGS) $(sha256objs) -o sha256\n\n%.mfs.o:        %.c\n                $(CC) $(CFLAGS) -DMAIN -DFORT -DSHA256 -c -o $@ $&lt;\n\n%.fs.o:         %.c\n                $(CC) $(CFLAGS) -DFORT -DSHA256 -c -o $@ $&lt;\n\n%.m.o:          %.c\n                $(CC) $(CFLAGS) -DMAIN -c -o $@ $&lt;\n\n%.o:            %.c\n                $(CC) $(CFLAGS) -c -o $@ $&lt;\n\nclean:\n                rm -f *~ \\#*\\# *.o<\/code><\/pre>\n\n\n\n<p>newressu.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;malloc.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;math.h&gt;\n#include &lt;sys\/time.h&gt;\n#include &lt;time.h&gt;\n\n\/\/#define SHA256 2 \/\/ in Makefile\n\n#ifdef SHA256\n#include \"sha256.h\"\n#endif\n\n\/\/#define FORT 2 \/\/ in Makefile\n\n#ifdef FORT\n#include \"fort.h\"\n#endif\n\n\/\/#define MAIN 2 \/\/ in Makefile\n\n#include \"newressu.h\"\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"Newressu version 2.6 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2013-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4nn!\";\n\nstatic unsigned long periods&#91;1024];\nstatic unsigned long genbytes=0;\nstatic unsigned long clockbytes=0;\n\nint size=5, type=10;\n\n#define RESSUT_BYTES 2048\n#define RESSU_BITS1_NEEDED 256\n#define RESSU_BITS2_NEEDED 300\n#define RESSU_MIN_ROUNDS 2\n#define RESSU_MIN_CLOCKBYTES 16384+1024\n\n#define aWRITE_SAMPLE 2\n#define aUSE_RANDOM 2\n#define USE_TIMER 2\n#define DEBUG_SORTED 2\n\n#ifdef MAIN\nstatic unsigned char samplefilename&#91;128]=\"newressusample.rnd\";\n#endif\nstatic unsigned char urandomfilename&#91;128]=\"\/dev\/urandom\";\n#ifdef USE_RANDOM\nstatic unsigned char randomfilename&#91;128]=\"\/dev\/random\";\n#endif\n\nstatic int ressut_bytes = RESSUT_BYTES;\nstatic unsigned char ressut&#91;RESSUT_BYTES];\nstatic int ressu_bits1_needed = RESSU_BITS1_NEEDED;\nstatic int ressu_bits2_needed = RESSU_BITS2_NEEDED;\nstatic int ressu_bits3_needed = RESSUT_BYTES;\nstatic int ressu_bits4_needed = RESSUT_BYTES;\n\n#define GENT_SIZE 1024\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos=0;\n\nint rndbits1;\nint rndbits2;\nint rndbits3;\nint rndbits4;\n\nint newressu_output=0;\n\nunsigned long long get_useconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec + 1000000 * tv.tv_sec);\n}\n\nvoid ressut_clear()\n{\n  memset(ressut, 0, sizeof(ressut));\n}\n\nstatic int stats=0;\n#define MORESECURE 2\n#define aDEBUG3 2\n\nstatic unsigned char ressu_clockbyte2() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}\n\nstatic unsigned char ressu_clockbyte() \/* JariK 2013 *\/\n{\n  unsigned char ch;\n\n  ch=ressu_clockbyte2();\n\n#ifdef MORESECURE\n  static unsigned int rndbits2pausecount=1000, rndbits2pausebase=0;\n  \n  if(--rndbits2pausecount == 0) {\n#ifdef FORT\n    if(input == INPUT_FORT ||\n       input == INPUT_FORTXOR)\n      rndbits2pausebase += cvar&#91;0] + 256 * cvar&#91;1];\n#endif    \n    rndbits2pausebase = rndbits2pausebase +\n      rndbits2pausecount +\n      clockbytes +\n      genbytes +\n      gent_pos +\n      time(NULL) +\n      get_useconds() +\n      ch;\n\n    int skip=ressut&#91;rndbits2pausebase % ressut_bytes];\n\n    while(skip&gt;0) { \/\/ compare usleep(skip);\n      ch=ressu_clockbyte2();\n      skip--;\n    }\n\n    \/\/\n    \/\/  calculate rndbits2\n    \/\/\n    rndbits2+=8;\n    \n    rndbits2pausecount=500+ressut&#91;(rndbits2pausebase + 1) % ressut_bytes]*4; \/\/ value 500-1500\n#ifdef DEBUG3\n    fprintf(stdout,\"\\n%05d\",pausecount);\n    newressu_output=1;\n#endif\n  }\n#ifdef DEBUG3\n  fprintf(stdout,\" %02x\",ch);\n  newressu_output=1;\n#endif\n\n#endif \/\/ #ifdef MORESECURE\n  return(ch);\n}\n\n#define RR8(byte,bits) ( ((byte) &gt;&gt; (bits)) | ((byte) &lt;&lt; (8 - (bits))) )\n#define RL8(byte,bits) ( ((byte) &gt;&gt; (8 - (bits))) | ((byte) &lt;&lt; (bits)) )\n\n#define aDEBUG5 2\n\nvoid ressu_genbytes_single(int size, unsigned char *buffer)\n{\n  int c, d;\n  unsigned char e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  for(c = 0; c &lt; 8; c++) {\n    for(d = 0; d &lt; size; d++) {\n      e = buffer&#91;d];\n      e = RL8(e,1); \/\/ rotate byte left 1 bits\n      \/\/e = RL8(e,3); \/\/ rotate byte left 3 bits\n      \/\/e = RR8(e,1); \/\/ rotate byte right 1 bits\n      byte = ressu_clockbyte();\n      if(prevbyte == -1)\n\tprevbyte = byte;\n      buffer&#91;d] = e^byte;\n      if(prevbyte != byte) {\n\tperiods&#91;count]++;\n\tclockbytes += count;\n\tcount = 0;\n\tprevbyte = byte;\n      }\n      count++;\n    }\n#ifdef DEBUG5\n    if(newressu_output)\n      fprintf(stdout, \"\\n\");\n    fprintf(stdout, \"single 1  \");\n    for(c = 0; c &lt; 32; c++) {\n      fprintf(stdout,\"%02x\", buffer&#91;c]);\n      newressu_output = 1;\n    }\n#endif\n    for(d = 0; d &lt; size; d++) {\n      f = (f + buffer&#91;d]) % size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n#ifdef DEBUG5\n    if(newressu_output)\n      fprintf(stdout,\"\\n\");\n    fprintf(stdout,\"single 2  \");\n    for(c = 0; c &lt; 32; c++) {\n      fprintf(stdout,\"%02x\",buffer&#91;c]);\n      newressu_output=1;\n    }\n#endif\n  }\n}\n\nvoid ressu_genbytes_fast(int size, unsigned char *buffer)\n{\n  int c;\n\n  clockbytes = 0;\n  for(c = 0; c &lt; RESSU_MIN_ROUNDS ||\n\tclockbytes &lt; RESSU_MIN_CLOCKBYTES; c++) {\n    ressu_genbytes_single(size, buffer);\n  }\n}\n\n#define aDEBUG6 2\n#define aDEBUG7 2\n#define aDEBUG8 2\n\nvoid ressu_genbytes(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c, d, e, f;\n  static int ressut_first = 1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  unsigned long prevperiods&#91;1024];\n  \n  for(c = 0; c &lt; size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut, 0, ressut_bytes);\n\tressut_first = 0;\n      }\n\n      clockbytes=0;\n      for(d = 0; d &lt; 1024; d++) {\n\tperiods&#91;d] = 0;\n      }\n      \n      rndbits1 = 0;\n      rndbits2 = 0;\n      rndbits3 = 0;\n      rndbits4 = 0;\n\n      int lim, lim1 = 0, lim2 = 0;\n      int lim1a, lim1b;\n      int high1, high2;\n\n      int rndbits3high;\n#ifdef DEBUG6\n      int rndbits4high;\n#endif\n      int rndbits4highdigits;\n      \n      for(d = 0;\n\t  rndbits1 &lt; ressu_bits1_needed ||\n\t  rndbits2 &lt; ressu_bits2_needed ||\n\t  rndbits3 &lt; ressu_bits3_needed ||\n\t  rndbits4 &lt; ressu_bits4_needed ||\n\t  d &lt; RESSU_MIN_ROUNDS ||\n\t    clockbytes &lt; RESSU_MIN_CLOCKBYTES; d++) {\n\n\n\t\/\/\n\t\/\/  calculate rndbits1\n\t\/\/\n\t\n\t\/\/ save previous round\n\n        for(e = 0; e &lt; 1024; e++) {\n\t  prevperiods&#91;e] = periods&#91;e];\n\t}\n\n\tressu_genbytes_single(ressut_bytes, ressut);\n\n\t\/\/ find new lim1\n\t\n\tlim = lim1;\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(prevperiods&#91;e] &gt; 0 &amp;&amp; prevperiods&#91;e] == lim) {\n\t    if(f == -1 || (periods&#91;e]&gt;0 &amp;&amp; f&lt;periods&#91;e])) {\n\t      f  = periods&#91;e];\n\t    }\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim = f;\n\n\tlim1a = lim;\n\t\n\t\/\/ find highest amount of chains\n\t\n\thigh1 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(high1 == -1 || high1 &lt; periods&#91;e]) {\n\t    high1 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and second highest\n\t\n\thigh2 = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (high2 == -1 &amp;&amp; periods&#91;e] &lt; high1) ||\n\t      (high2 &lt; periods&#91;e] &amp;&amp; periods&#91;e] &lt; high1) ) {\n\t    high2 = periods&#91;e];\n\t  }\n\t}\n\n\t\/\/ and average\n\n\tint psum = 0;\n\tint pcnt = 0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0) {\n\t    psum += periods&#91;e];\n\t    pcnt++;\n\t  }\n\t}\n\n\tlim1b = (int)((double)psum \/ pcnt);\n\t\n\t\/\/ find next smaller than average\n\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if( (f == -1 &amp;&amp; periods&#91;e] &lt; lim1b) ||\n\t      (f&lt;periods&#91;e] &amp;&amp; periods&#91;e] &lt; lim1b) ) {\n\t    f = periods&#91;e];\n\t  }\n\t}\n\n\tif(f != -1)\n\t  lim1b = f;\n\n\tif(lim == 0 || lim &gt; lim1b)\n\t  lim = lim1b;\n\n\t\/\/ if lim greater that second highest,\n\t\/\/ set to second highest\n\n\tif(lim &gt; high2) {\n\t  lim = high2;\n\t}\n\t\t\n\tlim1 = lim;\n\n\t\/\/ find next greater than lim\n\t\n\tf = -1;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; lim &amp;&amp;\n\t     (f == -1 || periods&#91;e] &lt; f))\n\t    f = periods&#91;e];\n\t}\n\tif(f != -1)\n\t  lim = f;\n\n\tlim2 = lim;\n\n\t\/\/ calculate rndbits1\n\t\t\n\trndbits1=0;\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0 &amp;&amp; periods&#91;e] &lt; lim) {\n\t    rndbits1 += periods&#91;e];\n\t  }\n\t}\n\t\n\t\/\/\n\t\/\/  calculate rndbits3\n\t\/\/\n\n\trndbits3high=0;\n\trndbits3=0;\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits3high &lt; periods&#91;e])\n\t    rndbits3high = periods&#91;e];\n\t}\n#ifdef DEBUG8\n\tfprintf(stdout,\"\\n%d:\", rndbits3high);\n#endif\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits3high &gt; periods&#91;e]) {\n\t    rndbits3 += periods&#91;e];\n#ifdef DEBUG8\n\t    if(periods&#91;e]&gt;0)\n\t      fprintf(stdout,\" %ld(%d)\", periods&#91;e],rndbits3);\n#endif\n\t  }\n\t}\n\n\t\/\/\n\t\/\/  calculate rndbits4\n\t\/\/\n\n\trndbits4highdigits=0;\n#ifdef DEBUG6\n\trndbits4high=0;\n#endif\n\trndbits4=0;\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &lt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4highdigits = (int)log10((double)periods&#91;e]) + 1;\n#ifdef DEBUG6\n\t    rndbits4high = periods&#91;e];\n#endif\n\t  }\n\t}\n#ifdef DEBUG6\n\tfprintf(stdout,\"\\n%d:\", rndbits4high);\n#endif\n\tfor(e=0; e &lt; 1024; e++) {\n\t  if(rndbits4highdigits &gt; (int)log10((double)periods&#91;e]) + 1) {\n\t    rndbits4 += periods&#91;e];\n#ifdef DEBUG6\n\t    if(periods&#91;e]&gt;0)\n\t      fprintf(stdout,\" %ld(%d)\", periods&#91;e],rndbits4);\n#endif\n\t  }\n\t}\n      } \/\/ for(d=0;\n\n      if(stats) {\n\t\/\/\n\t\/\/  display statistics\n\t\/\/\n\tfprintf(stdout, \"rounds: %d\", d);\n\tfor(e = 0; e &lt; 1024; e++) {\n\t  if(periods&#91;e] &gt; 0)\n\t    fprintf(stdout, \" %d:%lu\", e, periods&#91;e]);\n\t}\n\n#ifdef DEBUG_SORTED\n\t\n\tfprintf(stdout, \", sorted:\");\n\tint g = 0;\n\tfor(;;) {\n\t  f = -1;\n\t  for(e = 0; e &lt; 1024; e++) {\n\t    if( (f==-1 &amp;&amp; periods&#91;e]&gt;g) ||\n\t\t(periods&#91;e]&gt;g &amp;&amp; f&gt;periods&#91;e]) )\n\t      f = periods&#91;e];\n\t  }\n\t  if(f == -1)\n\t    break;\n\n\t  g=f;\n\t  fprintf(stdout,\" %d\", g);\n\t}\n\n#endif\n\tfprintf(stdout, \", high1:%d\", high1);\n\tfprintf(stdout, \", high2:%d\", high2);\n\tfprintf(stdout, \", lim1a:%d\", lim1a);\n\tfprintf(stdout, \", lim1b:%d\", lim1b);\n\tfprintf(stdout, \", lim1:%d\", lim1);\n\tfprintf(stdout, \", lim2:%d\", lim2);\n\tfprintf(stdout, \", div:%f\", (double)lim2 \/ lim1);\n\tfprintf(stdout, \", clockbytes:%ld\", clockbytes);\n\tfprintf(stdout, \", rndbits1:%d\", rndbits1);\n\tfprintf(stdout, \", rndbits2:%d\", rndbits2);\n\tfprintf(stdout, \", rndbits3high:%d\", rndbits3high);\n\tfprintf(stdout, \", rndbits3:%d\", rndbits3);\n\tfprintf(stdout, \", rndbits4highdigits:%d\", rndbits4highdigits);\n\tfprintf(stdout, \", rndbits4:%d\", rndbits4);\n\tfprintf(stdout, \"\\n\");\n\tfflush(stdout);\n      }\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n#ifdef DEBUG7\n  for(c = 0; c &lt; size; c++) {\n    if(c%32 == 0)\n      fprintf(stdout, \"\\ngenbytes  \");\n    fprintf(stdout, \"%02x\", buffer&#91;c]);\n    newressu_output = 1;\n  }\n  fprintf(stdout, \"\\n\");\n#endif\n  \n  genbytes+=size;\n}\n\nstatic unsigned char ressu_clockbyte_debug() \/* JariK 2013 *\/\n{\n  unsigned char ch;\n\n  ch=ressu_clockbyte2();\n#ifdef MORESECURE\n  static unsigned int pausecount=1000, pausebase=0;\n  \/\/ every 1001 bytes skip randon\n  \/\/ clockbytes by usleeping\n  if(--pausecount == 0) {\n#ifdef FORT\n    if(input == INPUT_FORT ||\n       input == INPUT_FORTXOR)\n      pausebase += cvar&#91;0] + 256 * cvar&#91;1];\n#endif    \n    pausebase = pausebase +\n      pausecount +\n      clockbytes +\n      genbytes +\n      gent_pos +\n      time(NULL) +\n      get_useconds() +\n      ch;\n    \n    int skip=ressut&#91;pausebase % ressut_bytes];\n    while(skip&gt;0) { \/\/ compare usleep(skip);\n      ch=ressu_clockbyte2();\n      skip--;\n    }\n\n    rndbits2+=8;\n    \n    pausecount=500+ressut&#91;(pausebase + 1) % ressut_bytes]*4; \/\/ value 500-1500\n  }\n#endif \/\/ #ifdef MORESECURE\n  return(ch);\n}\n\nvoid ressu_genbytes_single_debug(int size, unsigned char *buffer)\n{\n  int c, d;\n  unsigned char e, byte;\n  static int f = 0, prevbyte = -1, count = 0;\n\n  for(c = 0; c &lt; 8; c++) {\n    for(d = 0; d &lt; size; d++) {\n      e = buffer&#91;d];\n      e = RL8(e,1); \/\/ rotate byte left 1 bits\n      \/\/e = RL8(e,3); \/\/ rotate byte left 3 bits\n      \/\/e = RR8(e,1); \/\/ rotate byte right 1 bits\n      byte = ressu_clockbyte_debug();\n      if(prevbyte == -1)\n\tprevbyte = byte;\n      buffer&#91;d] = e^byte;\n      if(prevbyte != byte) {\n\tperiods&#91;count]++;\n\tclockbytes += count;\n\tcount = 0;\n\tprevbyte = byte;\n      }\n      count++;\n    }\n    for(d = 0; d &lt; size; d++) {\n      f = (f + buffer&#91;d]) % size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n  }\n}\n\nvoid ressu_genbytes_debug(int size, unsigned char *buffer) \/\/ 6.5.2021 JariK\n{\n  int c, d;\n  static int ressut_first=1,\n    ressut_pos = 0,\n    ressut_f = 0;\n  \n  for(c = 0; c &lt; size; c++) {\n    if(ressut_pos == 0) {\n      if(ressut_first) {\n\tmemset(ressut, 0, ressut_bytes);\n\tressut_first = 0;\n      }\n\n      rndbits2 = 0;\n      clockbytes = 0;\n\n      for(d = 0;rndbits2 &lt; ressu_bits2_needed ||\n\t  d &lt; RESSU_MIN_ROUNDS; d++) {\n\tressu_genbytes_single_debug(ressut_bytes, ressut);\n      }\n      \n      if(stats) {\n\tfprintf(stdout, \"rounds: %d\", d);\n\tfprintf(stdout, \", clockbytes:%ld\", clockbytes);\n\tfprintf(stdout, \", rndbits2:%d\", rndbits2);\n\tfprintf(stdout, \"\\n\");\n\tfflush(stdout);\n      }\n    } \/\/ if(ressut_pos == 0)\n    ressut_f = (ressut_f + ressut&#91;ressut_pos]) % ressut_bytes;\n    buffer&#91;c] ^= ressut&#91;ressut_f];\n    ressut_pos = (ressut_pos+1) % ressut_bytes;\n  } \/\/ for(c=0; c&lt;size; c++)\n\n#ifdef DEBUG7\n  for(c = 0; c &lt; size; c++) {\n    if(c % 32 == 0)\n      fprintf(stdout, \"\\ngenbytes  \");\n    fprintf(stdout, \"%02x\", buffer&#91;c]);\n    newressu_output = 1;\n  }\n  fprintf(stdout, \"\\n\");\n#endif\n\n  genbytes += size;\n}\n\nstatic void readfile_xor(int len,\n    unsigned char *buf,\n    unsigned char *filename)\n{\n  int c, n, n2;\n  unsigned char temp&#91;64];\n  FILE *fp1;\n\n  if((fp1 = fopen(filename, \"rb\"))\n      != NULL) {\n    while(len != 0) {\n      n = (len &lt; sizeof(temp)) ?\n          len : sizeof(temp);\n      n2=fread(temp, 1, n, fp1);\n      for(c = 0; c &lt; n2; c++)\n        buf&#91;c] ^= temp&#91;c];\n      len -= n2;\n      buf += n2;\n    }\n    fclose(fp1);\n  }\n}\n\nint input=0;\n\n#define aDEBUG9 2\n\nchar *randomgen&#91;] = { \"ressu\", \"debug\",\"fast\",\"single\",\"4\",\"5\",\"fort\",\"fortxor\",\"urandom\",\"random\" };\n\nvoid gent_clear()\n{\n  memset(gent,0,sizeof(gent));\n}\n\n#define aDEBUG17 2\n#define aDEBUG18 2\n\nint ressu_genbyte()\n{\n  unsigned char ch;\n\n  if(gent_pos == 0) {\n    if(input == INPUT_RESSU) \/\/ ressu prod\n      ressu_genbytes(sizeof(gent), gent);\n    else if(input == INPUT_DEBUG) \/\/ ressu debug\n      ressu_genbytes_debug(sizeof(gent), gent);\n    else if(input == INPUT_FAST) \/\/ ressu_fast\n      ressu_genbytes_fast(sizeof(gent),gent);\n    else if(input == INPUT_SINGLE) \/\/ ressu single\n      ressu_genbytes_single(sizeof(gent), gent);\n#ifdef FORT\n    else if(input == INPUT_FORT) \/\/ ressu fort\n      fort_random_data(sizeof(gent), gent);\n    else if(input == INPUT_FORTXOR) \/\/ ressu fort\n      fort_random_data_xor(sizeof(gent), gent);\n#endif\n    else if(input == INPUT_URANDOM) \/\/ urandom\n      readfile_xor(sizeof(gent), gent, urandomfilename);\n#ifdef USE_RANDOM\n    else if(input == INPUT_RANDOM) \/\/ random\n      readfile_xor(sizeof(gent), gent, randomfilename);\n#endif\n    else {\n      fprintf(stdout,\"%s: mode '%d'(%s) not available\\n\",\n\t      procname, input, randomgen&#91;input]);\n      exit(1);\n    }\n#ifdef DEBUG17\n    for(int c=0; c &lt; sizeof(gent); c++) {\n      if(c % 32 == 0)\n\tfprintf(stdout,\"\\ngenbyte   \");\n      fprintf(stdout,\"%02x\", gent&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n#endif\n  \n  } \/\/ if(gent_pos==0\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"{%02x}\",ch);\n#endif\n  return(ch);\n}\n\n\n#define aDEBUG19 2\n#define aDEBUG24 2\n\nunsigned long ressu_gen_limit(unsigned long limit)\n{\n  int c, bytes;\n  unsigned long word, highlimit;\n  \n  if(limit&lt;=0x100) { \/\/ 1 byte\n    highlimit=0x100;\n    bytes=1;\n  } else if(limit&lt;=0x10000) { \/\/ 2 bytes\n    highlimit=0x10000;\n    bytes=2;\n  } else if(limit&lt;=0x1000000) { \/\/ 3 bytes\n    highlimit=0x1000000;\n    bytes=3;\n  } else if(limit&lt;=(unsigned long)0x100000000) { \/\/ 4 bytes\n    highlimit=0x100000000;\n    bytes=4;\n  } else if(limit&lt;=(unsigned long)0x10000000000) { \/\/ 5 bytes\n    highlimit=0x10000000000;\n    bytes=5;\n  } else if(limit&lt;=(unsigned long)0x1000000000000) { \/\/ 6 bytes\n    highlimit=0x1000000000000;\n    bytes=6;\n  } else if(limit&lt;=(unsigned long)0x100000000000000) { \/\/ 7 bytes\n    highlimit=0x100000000000000;\n    bytes=7;\n  } else { \/\/ if(limit&lt;=(unsigned long)0xffffffffffffffff) { \/\/ 8 bytes\n    highlimit=0xffffffffffffffff;\n    bytes=8;\n  }\n\n  for(;;) {\n    word=0;\n    for(c=0;c&lt;bytes;c++)\n      word = word &lt;&lt; 8 | ressu_genbyte();\n    if(word &lt; (highlimit\/limit)*limit)\n      break;\n  }\n\n  word%=limit;\n  \n#ifdef DEBUG24\n  fprintf(stdout,\"\/\");\n#ifdef DEBUG19\n  fprintf(stdout,\"%d bytes: \", bytes);\n#endif\n  if(type==2)\n    fprintf(stdout,\"%lx\", word);\n  else if(type==8)\n    fprintf(stdout,\"%lo\", word);\n  else if(type==10)\n    fprintf(stdout,\"%lu\", word);\n  else if(type==16)\n    fprintf(stdout,\"%lx\", word);\n  else\n    fprintf(stdout,\"%lu\", word);\n  fprintf(stdout,\"\/\");\n  fflush(stdout);\n#endif\n\n  return(word);\n}\n\n#ifdef OLD1\n\n\/\/ Little faster on middle byte numbers (3,5,6,7),\n\/\/ try --rand &amp; --timer\n#define GENMIDBYTES 2\n\nint ressu_genbyte_limit(int limit) \/\/ 1 byte\n{\n  int c;\n  while((c=ressu_genbyte()) &gt;= (0x100\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" byte %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nint ressu_genshort() \/\/ 2 bytes\n{\n  return(ressu_genbyte() | ressu_genbyte()&lt;&lt;8);\n}\n\nint ressu_genshort_limit(int limit) \/\/ 2 bytes\n{\n  int c;\n  while((c=ressu_genshort()) &gt;= (0x10000\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" short %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#ifdef GENMIDBYTES\n\nint ressu_gen3bytes() \/\/ 3 bytes\n{\n  return(ressu_genshort() | ressu_genbyte()&lt;&lt;16);\n}\n\nint ressu_gen3bytes_limit(int limit) \/\/ 3 bytes\n{\n  int c;\n  while((c=ressu_gen3bytes()) &gt;= (0x1000000\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 3 bytes %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#endif \/\/ #ifdef GENMIDBYTES\n\nunsigned int ressu_genint() \/\/ 4 bytes\n{\n  return(ressu_genshort() | ressu_genshort()&lt;&lt;16);\n}\n\nunsigned int ressu_genint_limit(unsigned long limit) \/\/ 4 bytes\n{\n  unsigned int c;\n  while((c=ressu_genint()) &gt;= (((unsigned long)0x100000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" int %x(%d)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#ifdef GENMIDBYTES\n\nunsigned long ressu_gen5bytes() \/\/ 5 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_genbyte())&lt;&lt;32);\n}\n\nunsigned long ressu_gen5bytes_limit(unsigned long limit) \/\/ 5 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen5bytes()) &gt;= (((unsigned long)0x10000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 5 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nunsigned long ressu_gen6bytes() \/\/ 6 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_genshort())&lt;&lt;32);\n}\n\nunsigned long ressu_gen6bytes_limit(unsigned long limit) \/\/ 6 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen6bytes()) &gt;= (((unsigned long)0x1000000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 6 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\nunsigned long ressu_gen7bytes() \/\/ 7 bytes\n{\n  return(ressu_genint() | ((unsigned long)ressu_gen3bytes())&lt;&lt;32);\n}\n\n#define aDEBUG22\n\nunsigned long ressu_gen7bytes_limit(unsigned long limit) \/\/ 7 bytes\n{\n  unsigned long c;\n  while((c=ressu_gen7bytes()) &gt;= (((unsigned long)0x100000000000000)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" 7 bytes %lx(%ld)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n#endif \/\/ #ifdef GENMIDBYTES\n\nunsigned long ressu_genlong() \/\/ 8 bytes\n{\n  return(((unsigned long)ressu_genint()) | ((unsigned long)ressu_genint())&lt;&lt;32);\n}\n\nunsigned long ressu_genlong_limit(unsigned long limit) \/\/ 8 bytes\n{\n  unsigned long c;\n  while((c=ressu_genlong()) &gt;= (((unsigned long)0xffffffffffffffff)\/limit)*limit);\n#ifdef DEBUG19\n  fprintf(stdout,\" long %lx(%lu)\",c,c);\n  fflush(stdout);\n#endif\n  return(c%limit);\n}\n\n\nunsigned long ressu_gen_limit2(unsigned long limit)\n{\n  unsigned long c;\n\n  if(limit&lt;=0x100) \/\/ 1 byte\n    c=ressu_genbyte_limit(limit);\n  else if(limit&lt;=0x10000) \/\/ 2 bytes\n    c=ressu_genshort_limit(limit);\n#ifdef GENMIDBYTES\n  else if(limit&lt;=0x1000000) \/\/ 3 bytes\n    c=ressu_gen3bytes_limit(limit);\n#endif\n  else if(limit&lt;=(unsigned long)0x100000000) \/\/ 4 bytes\n    c=ressu_genint_limit(limit);\n#ifdef GENMIDBYTES\n  else if(limit&lt;=(unsigned long)0x10000000000) \/\/ 5 bytes\n    c=ressu_gen5bytes_limit(limit);\n  else if(limit&lt;=(unsigned long)0x1000000000000) \/\/ 6 bytes\n    c=ressu_gen6bytes_limit(limit);\n  else if(limit&lt;=(unsigned long)0x100000000000000) \/\/ 7 bytes\n    c=ressu_gen7bytes_limit(limit);\n#endif\n  else if(limit&lt;=(unsigned long)0xffffffffffffffff) \/\/ 8 bytes\n    c=ressu_genlong_limit(limit);\n  else\n    c=-1;\n\n#ifdef DEBUG24\n  fprintf(stdout,\"\/%ld\/\",c);\n#endif\n\n  return(c);\n}\n\n#endif\n\nvoid newressu_version()\n{\n  fprintf(stderr,\"%s\",programname); \/\/ touch these outside MAIN\n  fprintf(stderr,\", %s\",copyright);\n}\n\n#ifdef MAIN\n\n#include &lt;stdarg.h&gt;\n\n#define aDEBUG31\n\nstatic int stat_line_chars=0;\nstatic int stat_line_edchars=0;\n\nunsigned char *procname=NULL;\n\nstatic void stat_line_begin()\n{\n#ifdef DEBUG31\n  fprintf(stderr,\"\\n\");\n#else\n  fprintf(stderr,\"\\r\");\n#endif  \n  stat_line_edchars=stat_line_chars;\n  stat_line_chars=0;\n}\n\nstatic void stat_line_printf(const unsigned char *format, ...)\n{\n  int count;\n  va_list args;\n  static unsigned char *stat_line_buf;\n  static size_t stat_line_buf_length;\n\n  va_start(args, format);\n  count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;\n  va_end(args);\n  if(stat_line_buf_length &lt; count) {\n    stat_line_buf_length=count;\n    stat_line_buf=realloc(stat_line_buf, stat_line_buf_length);\n    va_start(args, format);\n    count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;\n    va_end(args);\n  }\n  fprintf(stderr,\"%s\",stat_line_buf);\n  stat_line_chars+=strlen(stat_line_buf);\n}\n\n#define READABLE_NUMBER_BIN 2\n\n#ifdef READABLE_NUMBER_BIN\n#define READABLE_NUMBER_HIGH 1023\n#define READABLE_NUMBER_DIVIDER 1024\n#else\n#define READABLE_NUMBER_HIGH 999\n#define READABLE_NUMBER_DIVIDER 1000\n#endif\n\n#define READABLE_NUMBER_WIDTH 32\n\nstatic void stat_line_readable(unsigned long length)\n{\n  int c, low;\n  double length2;\n  unsigned char buf10&#91;10];\n  \/\/ B = byte\n  \/\/ K = kilo   10^3   2^10\n  \/\/ M = mega   10^6   2^20\n  \/\/ G = giga   10^9   2^30\n  \/\/ T = tera   10^12  2^40\n  \/\/ P = peta   10^15  2^50\n  \/\/ E = exa    10^18  2^60\n  \/\/ Z = zetta  10^21  2^70\n  \/\/ Y = yotta  10^24  2^80\n  char units&#91;] = \"BKMGTPEZY\";\n\n  strcpy(buf10,\"***\");\n  low=0;\n\n  for(c=0; length&gt;=low &amp;&amp;\n      c&lt;sizeof(units)-1; c++) {\n    if(length&gt;=low &amp;&amp;\n       length&lt;=READABLE_NUMBER_HIGH) {\n      if(units&#91;c]=='B')\n        sprintf(buf10,\"%ld\", length);\n      else if(units&#91;c]=='K')\n\tsprintf(buf10,\"%ld%cB\", length, units&#91;c]);\n      else if(length==length2)\n\tsprintf(buf10,\"%ld%cB\", length, units&#91;c]);\n      else\n\tsprintf(buf10,\"%.1f%cB\", length2, units&#91;c]);\n\t\n      break;\n    }\n    length2=(double)length\/READABLE_NUMBER_DIVIDER;\n    length\/=READABLE_NUMBER_DIVIDER;\n    low=1;\n  }\n  stat_line_printf(\"%s\",buf10);\n}\n\nvoid stat_line_end()\n{\n  int c,d;\n\n  \/\/ previous line longer than this one,\n  \/\/ overwrite with spaces and backspace to\n  \/\/ end\n  \n  if(stat_line_edchars&gt;stat_line_chars) {\n    d=stat_line_edchars-stat_line_chars;\n    for(c=0;c&lt;d;c++) {\n#ifdef DEBUG31\n      fprintf(stderr,\"*\");\n#else\n      fprintf(stderr,\" \");\n#endif\n    }\n    for(c=0;c&lt;d;c++)\n      fprintf(stderr,\"\\b\");\n  }\n  fflush(stderr);\n}\n\nint help=0;\n\nstatic int utf8characters(unsigned char *buf)\n{\n  int characters;\n  unsigned char *p;\n  \n  p=buf;\n  characters=0;\n  while(*p!='\\0') {\n    if(*p&lt;0x80 || \/\/ ascii char\n       *p&gt;0xbf) \/\/ first utf8 byte\n      characters++;\n    p++;\n  }\n  return(characters);\n}\n\n#define aDEBUG29 2\n\nint utf8lengths(unsigned char *buf)\n{\n  int lengths,len,first=1;\n  unsigned char *p;\n\n#ifdef DEBUG29 \n  fprintf(stdout,\"digits    %s\",buf);\n  fprintf(stdout,\"\\nlengths   \");\n#endif\n  \n  p=buf;\n  len=0;\n  lengths=-1;\n  first=1;\n\n  while(*p!='\\0') {\n    if(!first &amp;&amp;\n       (*p&lt;0x80 || \/\/ ascii char\n\t*p&gt;0xbf)) { \/\/ first utf8 byte\n#ifdef DEBUG29\n      fprintf(stdout,\"%d\",len);\n#endif\n      if(lengths==-1)\n\tlengths=len;\n      else if(lengths!=len)\n\tlengths=0;\n      len=0;\n    }\n    p++;\n    len++;\n    first=0;\n  }\n\n#ifdef DEBUG29\n  fprintf(stdout,\"%d\",len);\n#endif\n  if(lengths==-1)\n    lengths=len;\n  else if(lengths!=len)\n    lengths=0;\n\n#ifdef DEBUG29\n  fprintf(stdout,\"\\nlengths   %d\\n\\n\",lengths);\n#endif\n  return(lengths);\n}\n\n#define aDEBUG42 2\n\nstatic void codetoutf8(unsigned char *buf2, unsigned long code)\n{\n  unsigned char *buf;\n\n  buf=buf2;\n  if(code&lt;=0x7f) {\n    *buf++=code;\n  } else if(code&lt;=0x7ff) {            \/\/ 110xxxxx 10xxxxxx\n    *buf++=(0xc0 | ((code&gt;&gt;6)&amp;0x1f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0xffff) {           \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n    *buf++=(0xe0 | ((code&gt;&gt;12)&amp;0x0f));\n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));\n    *buf++=(0x80 | (code&amp;0x3f));\n  } else if(code&lt;=0x10ffff) {         \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *buf++=(0xf0 | ((code&gt;&gt;18)&amp;0x07));\n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffff) {        \/\/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xf8 | ((code&gt;&gt;24)&amp;0x03));\n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x7fffffff) {       \/\/ 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xfc | ((code&gt;&gt;30)&amp;0x01));\n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0xfffffffff) {      \/\/ 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xfe);\n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  } else if(code&lt;=0x3ffffffffff) {    \/\/ 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx \/\/ these not yet needed\n    *buf++=(0xff);\n    *buf++=(0x80 | ((code&gt;&gt;36)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;30)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;24)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;18)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;12)&amp;0x3f));      \n    *buf++=(0x80 | ((code&gt;&gt;6)&amp;0x3f));      \n    *buf++=(0x80 | ((code&amp;0x3f)));      \n  }\n  *buf='\\0';\n\n#ifdef DEBUG42\n  int c,print;\n\n  fprintf(stdout,\"codepoint: %lx\",code);\n\n  fprintf(stdout,\", bin:\");\n\n  print=0;\n  for(c=(sizeof(code)*8)-1;c&gt;=0;c--) {\n    int bit=(code&gt;&gt;c)&amp;1;\n    if(bit!=0)\n      print=1;\n    if(print) {\n      fprintf(stdout,\"%d\",bit);\n      if(c&gt;0 &amp;&amp; c%8==0)\n\tfprintf(stdout,\"|\");\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  print=0;\n  fprintf(stdout,\"%lo\",code);\n\n  fprintf(stdout,\", utf8: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\"%02x\",buf2&#91;c]);\n  }\n\n  fprintf(stdout,\", bin: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    if(c&gt;0)\n      fprintf(stdout,\"|\");\n    for(int d=7;d&gt;=0;d--) {\n      fprintf(stdout,\"%d\",buf2&#91;c]&gt;&gt;d&amp;1);\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\" %3o\",buf2&#91;c]);\n  }\n  \n  fprintf(stdout,\", character: %s\",buf2);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#ifdef NOTUSED\n\n#define aDEBUG43 2\n\nstatic void utf8tocode(unsigned long *code, unsigned char *buf2)\n{\n  unsigned char *buf;\n  \n  *code=0;\n  buf=buf2;\n  \n  if(*buf&lt;=0x7f) {                  \/\/ 0xxxxxxx\n    *code=*buf;\n  } else if(*buf&lt;0xc0) {            \/\/ 110xxxxx 10xxxxxx\n    *code=0;\n  } else if(*buf&lt;0xe0) {            \/\/ 110xxxxx 10xxxxxx\n    *code=*buf++&amp;0x1f;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf&lt;0xf0) {            \/\/ 1110xxxx 10xxxxxx 10xxxxxx\n    *code=*buf++&amp;0x0f;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf&lt;0xf8) {            \/\/ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code=*buf++&amp;0x07;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf&lt;0xfc) {            \/\/ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code=*buf++&amp;0x03;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf&lt;0xfe) {            \/\/ 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    *code=*buf++&amp;0x01;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf&lt;0xff) {            \/\/ 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    buf++;\n    *code=*buf++&amp;0x3f;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  } else if(*buf==0xff) {            \/\/ 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n    buf++;\n    *code=*buf++&amp;0x3f;\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n    *code=(*code&lt;&lt;6)+(*buf++&amp;0x3f);\n  }\n#ifdef DEBUG43\n  int c;\n\n  fprintf(stdout,\"character: %s\",buf2);\n\n  fprintf(stdout,\", utf8: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\"%02x\",buf2&#91;c]);\n  }\n\n  fprintf(stdout,\", bin: \");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    if(c&gt;0)\n      fprintf(stdout,\"|\");\n    for(int d=7;d&gt;=0;d--)\n      fprintf(stdout,\"%d\",buf2&#91;c]&gt;&gt;d&amp;1);\n  }\n\n  fprintf(stdout,\", oct:\");\n  for(c=0;c&lt;8;c++) {\n    if(buf2&#91;c]=='\\0')\n      break;\n    fprintf(stdout,\" %3o\",buf2&#91;c]);\n  }\n  \n  fprintf(stdout,\", codepoint: %lx\",*code);\n  fprintf(stdout,\", bin:\");\n  int print=0;\n  for(c=(sizeof(code)*8)-1;c&gt;=0;c--) {\n    int bit=(*code&gt;&gt;c)&amp;1;\n    if(bit!=0)\n      print=1;\n    if(print) {\n      fprintf(stdout,\"%d\",bit);\n      if(c&gt;0 &amp;&amp; c%8==0)\n\tfprintf(stdout,\"|\");\n    }\n  }\n\n  fprintf(stdout,\", oct:\");\n  fprintf(stdout,\"%lo\",*code);\n  \n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#endif\n\nint characterlengths=0; \/\/ 0 multiple lengths, x lengths are same\n\n#define aDEBUG30 2\n\nstatic void utf8getcharacter(int size, unsigned char *buf, int n, unsigned char *string)\n{\n  int d;\n  unsigned char *p,*q;\n  \n  d=0;\n  p=string;\n  q=buf;\n\n  \/\/ find first byte of character\n\n  if(characterlengths!=0)\n    p+=characterlengths*n;\n  else {\n    while(*p!='\\0') {\n      if(*p&lt;0x80 || \/\/ ascii char\n\t *p&gt;0xbf) { \/\/ first utf8 char\n\tif(d==n)\n\t  break;\n\td++;\n      }\n      p++;\n    }\n  }\n\n  \/\/ copy first byte and rest\n  \/\/ of character\n  \n  if(*p!='\\0') {\n    *q++=*p; \/\/ copy first byte\n    if(*p&gt;0xbf) { \/\/ if first is utf8 char\n      p++;\n      for(;;) {\n\tif(*p&gt;0xbf || \/\/ first utf8 char\n\t   *p&lt;0x80 || \/\/ ascii char\n\t   *p=='\\0')  \/\/ end of file\n\t  break;\n\t*q++=*p++; \/\/ copy rest of the bytes\n      }\n    }\n  }\n  *q='\\0';\n\n#ifdef DEBUG30\n  fprintf(stdout,\"%s: utf8getcharacter:\",procname);\n  fprintf(stdout,\" string: %s\",string);\n  fprintf(stdout,\", n: %d\",n);\n  fprintf(stdout,\", character: %s\",buf);\n  fprintf(stdout,\", characterlengths: %d\",characterlengths);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nstatic void utf8getcharacter1(int size, unsigned char *buf, int n, unsigned char *string)\n{\n  unsigned char *p,*q;\n  \n  p=string;\n  q=buf;\n\n  \/\/ find first byte of character\n\n  p+=n;\n\n  \/\/ copy first byte and rest\n  \/\/ of character\n  \n  if(*p!='\\0') {\n    *q++=*p; \/\/ copy first byte\n    if(*p&gt;0xbf) { \/\/ if first is utf8 char\n      p++;\n      for(;;) {\n\tif(*p&gt;0xbf || \/\/ first utf8 char\n\t   *p&lt;0x80 || \/\/ ascii char\n\t   *p=='\\0')  \/\/ end of file\n\t  break;\n\t*q++=*p++; \/\/ copy rest of the bytes\n      }\n    }\n  }\n  *q='\\0';\n\n#ifdef DEBUG30\n  fprintf(stdout,\"%s: utf8getcharacter:\",procname);\n  fprintf(stdout,\" string: %s\",string);\n  fprintf(stdout,\", n: %d\",n);\n  fprintf(stdout,\", character: %s\",buf);\n  fprintf(stdout,\", characterlengths: %d\",characterlengths);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\n#define aDEBUG45 2\n\nint digitscount=10;\n\nstatic void out_word(int size, unsigned char *buf, unsigned char *digits, unsigned long word2) \/\/ 8.5.2021 JariK\n{\n  int c, d, len;\n  unsigned long word;\n  unsigned char string&#91;132], character&#91;32];\n\n  \/\/digitscount = utf8characters(digits);\n  word=word2;\n  len=0;\n  string&#91;0]='\\0';\n\n  if(word==0 || digitscount&lt;2) {\n    \/\/ zero\n    utf8getcharacter(sizeof(character),character,0,digits);\n    if(len+strlen(character)&lt;sizeof(string)) {\n      strcat(string,character);\n      len+=strlen(character);\n    }\n  } else {\n    \/\/ non zero\n    while(word&gt;0) {\n      utf8getcharacter(sizeof(character),character,word%digitscount,digits);\n      if(len+strlen(character)&lt;sizeof(string)) {\n\tstrcat(string,character);\n\tlen+=strlen(character);\n      }\n      word\/=digitscount;\n    }\n  }\n\n  \/\/ reverse string\n  \n  *buf='\\0';\n  len=0;\n  d=utf8characters(string);\n  for(c=d-1;c&gt;=0;c--) {\n    utf8getcharacter(sizeof(character),character,c,string);\n    if(len+strlen(character)&lt;size) {\n      strcat(buf,character);\n      len+=strlen(character);\n    }\n  }\n\n#ifdef DEBUG45\n  fprintf(stdout,\"]\\n%s: out_word: \",procname);\n  fprintf(stdout,\" reverse string: %s\",string);\n  fprintf(stdout,\", digits: %s\",digits);\n  fprintf(stdout,\", int: %lu\",word2);\n  fprintf(stdout,\"\\n&#91;\");\n#endif\n}\n\nstatic void out_word_10(int size, unsigned char *buf, unsigned long word2) \/\/ 8.5.2021 JariK\n{\n  int c, d, len;\n  unsigned long word;\n  unsigned char string&#91;132], character&#91;32];\n  unsigned char *digits=\"0123456789\";\n  int digitscount=10;\n  \n  \/\/digitscount = utf8characters(digits);\n  word=word2;\n  len=0;\n  string&#91;0]='\\0';\n\n  if(word==0 || digitscount&lt;2) {\n    \/\/ zero\n    utf8getcharacter1(sizeof(character),character,0,digits);\n    if(len+strlen(character)&lt;sizeof(string)) {\n      strcat(string,character);\n      len+=strlen(character);\n    }\n  } else {\n    \/\/ non zero\n    while(word&gt;0) {\n      utf8getcharacter1(sizeof(character),character,word%digitscount,digits);\n      if(len+strlen(character)&lt;sizeof(string)) {\n\tstrcat(string,character);\n\tlen+=strlen(character);\n      }\n      word\/=digitscount;\n    }\n  }\n\n  \/\/ reverse string\n  \n  *buf='\\0';\n  len=0;\n  d=utf8characters(string);\n  for(c=d-1;c&gt;=0;c--) {\n    utf8getcharacter1(sizeof(character),character,c,string);\n    if(len+strlen(character)&lt;size) {\n      strcat(buf,character);\n      len+=strlen(character);\n    }\n  }\n\n#ifdef DEBUG45\n  fprintf(stdout,\"]\\n%s: out_word: \",procname);\n  fprintf(stdout,\" reverse string: %s\",string);\n  fprintf(stdout,\", digits: %s\",digits);\n  fprintf(stdout,\", int: %lu\",word2);\n  fprintf(stdout,\"\\n&#91;\");\n#endif\n}\n\n#define aDEBUG48 2\n\nstatic void in_word(unsigned long *word, unsigned char *digits, unsigned char *buf)\n{\n  int c,d,e,f,ok;\n  unsigned char character&#91;32], character2&#91;32];\n\n  *word=0;\n  d=utf8characters(buf);\n  f=utf8characters(digits);\n\n  for(c=0;c&lt;d;c++) {\n    utf8getcharacter(sizeof(character2),character2,c,buf);\n    ok=0;\n    for(e=0;e&lt;f;e++) {\n      utf8getcharacter(sizeof(character),character,e,digits);\n      if(!strcmp(character,character2)) {\n\tok=1;\n\tbreak;\n      }\n    }\n    if(ok) {\n      *word=((*word)*f)+e;\n    } else {\n      fprintf(stdout,\"%s: in_word:\",procname);\n      fprintf(stdout,\" illegal digit '%s'\\n\",character2);\n      help=1;\n    }\n  }\n\n#ifdef DEBUG48\n  fprintf(stdout,\"%s: in_word:\",procname);\n  fprintf(stdout,\" word: %lu\",*word);\n  fprintf(stdout,\", digits: %s\",digits);\n  fprintf(stdout,\", string: %s\",buf);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nstatic void line_clear(int *len, unsigned char **buf)\n{\n  if(*len&lt;1) {\n    *len=129;\n    *buf=realloc(*buf,*len);\n  }\n  **buf='\\0';\n}\n\nstatic int line_add_string_sort(int *len, unsigned char **buf, unsigned char *string)\n{\n  int cmp,count,add;\n  unsigned char *p;\n\n  p=*buf;\n  add=1;\n  while(*p!='\\0') {\n    cmp=strncmp(string,p,strlen(string));\n    if(cmp&gt;0) {\n      while(*p!=' ' &amp;&amp; *p!='\\0') \/\/ find next space\n\tp++;\n      while(*p==' ' &amp;&amp; *p!='\\0') \/\/ find next non space\n\tp++;\n    } else if(cmp==0) {\n      add=0;\n      break;\n    } else {\n      break;\n    }\n  }\n\n  if(add) {\n    count=strlen(*buf)+strlen(string)+1+1;\n    if(*buf==NULL || count&gt;*len) {\n      int diff=p-*buf;\n      *len = *len + 128;\n      *buf=realloc(*buf,*len);\n      p=*buf+diff;\n    }\n    memmove(p+strlen(string)+1,p,strlen(p)+1);\n    memmove(p,string,strlen(string));\n    p+=strlen(string);\n    *p=' ';\n  }\n\n  return(add);\n}\n\nstatic void line_get_string(int len, unsigned char *buf, int n, unsigned char *string)\n{\n  int e,ok,count;\n  unsigned char *p,*q;\n\n  ok=0;\n  p=string;\n  e=0;\n\n  while(*p!='\\0') {\n    if(e==n) {\n      ok=1;\n      break;\n    }\n    while(*p!=' ' &amp;&amp; *p!='\\0') \/\/ find next space\n      p++;\n    while(*p==' ' &amp;&amp; *p!='\\0') \/\/ find next non space\n      p++;\n    e++;\n  }\n  if(ok) {\n    q=buf;\n    count=0;\n    while(*q!=' ' &amp;&amp; *q!='\\0') {\n      if(++count&lt;len)\n\t*q++=*p;\n      p++;\n    }\n    *q='\\0';\n  } else {\n    buf&#91;0]='\\0';\n  }\n}\n\nstatic int zero=1, sspace=0, snewline=0,\n  scrlf=1, chars=72, pchars=0, charwidth=1, charspaces=0,\n  words=0, pwords=0,\n  plinesdigits=5, slineno=1, screen=0,\n  quiet=0, sort=0, unique=0, sample=0;\n#ifdef DEBUG51\nstatic int limitsize=0,\n#endif\nstatic unsigned long long lines=10, plines=0, ptotallines=0;\nstatic unsigned long limit, word;\nstatic unsigned char *digits=\"0123456789\", character&#91;32];\nstatic unsigned char digitstemp&#91;256], *digitsext=NULL;\nstatic unsigned char linenobuf&#91;1024];\n\n#define aDEBUG51 2\n\nstatic void readword(unsigned char *buf)\n{\n  int d,e;\n  unsigned char temp1024&#91;1024];\n  \n  if(limit!=0) {\n    word=0;\n    \n    if(zero) {\n      word=ressu_gen_limit(limit); \/\/ include zeroes\n    } else if(limit&gt;=1) {\n      while((word=ressu_gen_limit(limit))==0); \/\/ skip zeroes\n    }\n#ifdef DEBUG51\n    if(type==2)\n      fprintf(stdout,\"(%0*lx)\",limitsize,word);\n    else if(type==8)\n      fprintf(stdout,\"(%0*lo)\",limitsize,word);\n    else if(type==10)\n      fprintf(stdout,\"(%0*lu)\",limitsize,word);\n    else if(type==16)\n      fprintf(stdout,\"(%0*lx)\",limitsize,word);\n    else {\n      fprintf(stdout,\"(%02lu)\",word);\n    }\n#endif\n\t  \n    out_word(sizeof(temp1024),temp1024,digits,word);\n\t  \n    \/\/ fill leading zeroes\n    \n    buf&#91;0]='\\0';\n    utf8getcharacter(sizeof(character),character,0,digits);\n    for(d=size-utf8characters(temp1024);d&gt;0;d--) {\n      strcat(buf,character);\n    }\n\t  \n    \/\/ rest of the number\n\t  \n    strcat(buf,temp1024);\n\t  \n  } else if(digits!=NULL) {\n\t  \n    buf&#91;0]='\\0';\n\t  \n#ifdef DEBUG51\n    fprintf(stdout,\"(\");\n#endif\n    \/\/ fill whole word digit by digit\n    for(d=0;d&lt;size;d++) {\n      if(digits&#91;0]=='0' &amp;&amp; !zero)\n\te=ressu_gen_limit(digitscount-1)+1;\n      else\n\te=ressu_gen_limit(digitscount);\n      utf8getcharacter(sizeof(temp1024),temp1024,e,digits);\n#ifdef DEBUG51\n      fprintf(stdout,\"%s\",temp1024);\n      if(charspaces==1)\n\tfputc(' ',stdout);\n#endif\n      strcat(buf,temp1024);\n    }\n#ifdef DEBUG51\n    fprintf(stdout,\")\");\n#endif\n  }\n}\n\n#ifdef OLD1\nstatic void readword(unsigned char *buf)\n{\n  int d,e;\n  unsigned char temp1024&#91;1024];\n  \n  if(limit!=0) {\n    word=0;\n    \n    if(zero) {\n      word=ressu_gen_limit(limit); \/\/ include zeroes\n#ifdef DEBUG51\n      if(type==2)\n\tfprintf(stdout,\"(%02lx)\",word);\n      else if(type==8)\n\tfprintf(stdout,\"(%02lo)\",word);\n      else if(type==10)\n\tfprintf(stdout,\"(%02ld)\",word);\n      else if(type==16)\n\tfprintf(stdout,\"(%02lx)\",word);\n      else\n\tfprintf(stdout,\"(%02ld)\",word);\n#endif\n    } else if(limit&gt;=1) {\n      while((word=ressu_gen_limit(limit))==0); \/\/ skip zeroes\n    }\n\t  \n    out_word(sizeof(temp1024),temp1024,digits,word);\n\t  \n    \/\/ fill leading zeroes\n    \n    buf&#91;0]='\\0';\n    utf8getcharacter(sizeof(character),character,0,digits);\n    for(d=size-utf8characters(temp1024);d&gt;0;d--) {\n      strcat(buf,character);\n    }\n\t  \n    \/\/ rest of the number\n\t  \n    strcat(buf,temp1024);\n\t  \n  } else if(digits!=NULL) {\n\t  \n    buf&#91;0]='\\0';\n    \/\/digitscount=utf8characters(digits);\n\t  \n    \/\/ fill whole word digit by digit\n\t  \n    \/\/fprintf(stdout,\"&#91;\");\n    for(d=0;d&lt;size;d++) {\n      if(digits&#91;0]=='0' &amp;&amp; !zero)\n\te=ressu_gen_limit(digitscount-1)+1;\n      else\n\te=ressu_gen_limit(digitscount);\n      utf8getcharacter(sizeof(temp1024),temp1024,e,digits);\n      \/\/fprintf(stdout,\"%s\",temp1024);\n      strcat(buf,temp1024);\n    }\n    \/\/fprintf(stdout,\"]\");\n  }\n}\n\n#endif\n\nstatic int line_number_length()\n{\n  int c;\n  out_word_10(sizeof(linenobuf),linenobuf,lines-1);\n  c=strlen(linenobuf);\n  if(c&lt;5)\n    c=5;\n  return(c);\n}\n\nstatic void print_line_number()\n{\n  unsigned char linenobuf&#91;32];\n  \n  if(pwords==0 &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*llu\",plinesdigits,plines);\n    fprintf(stdout,\"%s\",linenobuf);\n    fprintf(stdout,\" \");\n  }\n}\n\nstatic int calc_spaces()\n{\n  int spaces;\n\n  spaces=0;\n  \n  if(sspace&gt;=2 &amp;&amp;\n     \/\/ space between word groups\n     ( (pwords&gt;0 &amp;&amp; pwords%sspace==0) ||\n       \/\/ space after linenumber\n       \/\/ are not printed if\n       \/\/ not printing linenumber\n       (slineno &amp;&amp; pwords==0) ) )\n    spaces++;\n    \n  if(sspace &amp;&amp;\n     \/\/ space between words\n     ( (pwords&gt;0) ||\n       \/\/ space after linenumber\n       (slineno &amp;&amp; pwords==0) ) ) \n    spaces++;\n\n  return(spaces);\n}\n\nstatic void print_spaces()\n{\n  int sp;\n\n  for(sp=calc_spaces();sp&gt;0;sp--)\n    fprintf(stdout,\" \");\n}\n\nstatic void print_word(unsigned char *buf)\n{\n  int e;\n  \n  if(size!=0) {\n    if(charspaces==0) {\n      fprintf(stdout,\"%s\",buf);\n    } else {\n      for(e=0;e&lt;size;e++) {\n\tunsigned char temp1024&#91;1024];\n\tutf8getcharacter(sizeof(temp1024),temp1024,e,buf);\n\tfprintf(stdout,\"%s\",temp1024);\n\tfputc(' ',stdout);\n      }\n    }\n  } else {\n    fprintf(stdout,\"%s\",buf);\n    if(charspaces==1) {\n      fputc(' ',stdout);\n    }\n  }\n}\n\n#ifdef OLD1\n\nstatic void print_word(unsigned char *buf)\n{\n  if(charspaces==1) {\n    fprintf(stdout,\"%*s \",size,buf);\n  } else if(size!=0) {\n      fprintf(stdout,\"%*s\",size,buf);\n  } else {\n    fprintf(stdout,\"%s\",buf);\n  }\n}\n\n#endif\n\n#ifdef SHA256\n\nstatic void newressu_file_digest(char *filename,unsigned char *hash)\n{\n  int c;\n  unsigned char buffer&#91;1024];\n  FILE *fp1;\n  HashCtx ctx;\n  \n  HashInit(&amp;ctx);\n  if((fp1 = fopen(filename, \"rb\"))!=NULL) {\n    while((c=fread(buffer, 1, sizeof(buffer), fp1)) &gt; 0)\n      HashUpdate(&amp;ctx, buffer, c);\n    fclose(fp1);\n  }\n  HashFinal(hash, &amp;ctx);  \n}\n\n#endif\n\n#define aDEBUG55 2\n\nvoid digits_add_string(unsigned char **digits, char *str)\n{\n  int digitssize;\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\",*digits);\n  fprintf(stdout,\"\\nadddigits %s\",str);\n#endif\n  digitssize=0;\n  if(*digits!=NULL)\n    digitssize+=strlen(*digits);\n  digitssize+=strlen(str);\n  *digits=realloc(*digits,digitssize+1);\n  strcat(*digits,str);\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\",*digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\nvoid digits_add_limits(unsigned char **digits, int start, int end)\n{\n  int c, digitssize;\n  unsigned char buffer&#91;10];\n\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nolddigits %s\",*digits);\n  fprintf(stdout,\"\\nadddigits start:%d, end:%d\",start,end);\n#endif\n  digitssize=0;\n  if(*digits!=NULL)\n    digitssize+=strlen(*digits);\n  \n  for(c=start;c&lt;=end;c++) {\n    codetoutf8(buffer,c);\n    digitssize+=strlen(buffer);\n  }\n  *digits=realloc(*digits,digitssize+1);\n  for(c=start;c&lt;=end;c++) {\n    codetoutf8(buffer,c);\n    strcat(*digits,buffer);\n  }\n#ifdef DEBUG55\n  fprintf(stdout,\"\\nnewdigits %s\",*digits);\n  fprintf(stdout,\"\\n\");\n#endif\n}\n\ndouble getseconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv,NULL);\n  return((double)tv.tv_sec+(double)tv.tv_usec\/1000000);\n}\n\nvoid dump_sample()\n{\n\/\/sample file size = CLIM*DLIM*BLKSIZE\n#define CLIM 8192 \/\/ outer loop\n#define DLIM 256 \/\/ inner loop\n#define BLKSIZE 4096 \/\/ block size\n\n#define STAT_LINE_READY 2\n#define STAT_LINE_NOW 2\n#define STAT_LINE_ANIM 2\n    \n#define TIMEFORMAT \"%H:%M %Z\"\n#define TIMEFORMAT2 \"%a %H:%M %Z\"\n#define DATEFORMAT \"%a %d %b %Y\"\n    \n    unsigned int c, d;\n    unsigned char buffer&#91;BLKSIZE];\n    FILE *fp1;\n    time_t secondsstart, secondsnow;\n#ifdef STAT_LINE_ANIM\n    long int secs, prev_secs=-1;\n    int crs=0;\n#endif\n\n    if((fp1=fopen(samplefilename,\"a\")) != NULL) {\n\n      secondsstart=time(NULL);\n\n      for(c=0;c&lt;CLIM;c++) {\n\tsecondsnow=time(NULL);\n\t\n\t\/\/ print status line:\n\t\/\/ blk 10, written 10MB, 269KB\/sec, left 8 h 38 m, ready at Sat 17 Jul 2021 01:57:43 EEST, now Fri 17:19:32 EEST\n\t\n\tstat_line_begin();\n\tstat_line_printf(\"\\rblk %d, written \",c);\n\tstat_line_readable((unsigned long)c*DLIM*BLKSIZE);\n\t\n\tif(c&gt;0) {\n\t  stat_line_printf(\", \");\n\t  stat_line_readable((unsigned long)((double)c*DLIM*BLKSIZE\/(secondsnow-secondsstart)) );\n\t  stat_line_printf(\"\/sec\");\n\n\t  char timebuf&#91;128], timebuf2&#91;128];\n\t  \n#ifdef STAT_LINE_NOW\n\n\t  \/\/ print now\n\t  \n\t  stat_line_printf(\", now\");\n\t  strftime(timebuf,sizeof(timebuf),TIMEFORMAT2,\n\t\t   localtime((time_t *)&amp;secondsnow));\n\t  stat_line_printf(\" %s\",timebuf);\n#endif\n\n\t  \/\/ print left\n\t  \n\t  long int secondsleft=(int)((((double)secondsnow-secondsstart)\/c)*(CLIM-c) );\n\t  long int secondsleft2;\n\t  long int temp,timeprinted=0;\n\n\t  secondsleft2=secondsleft;\n\t  stat_line_printf(\", left\");\n\t  \n\t  temp=secondsleft2\/(24*3600);\n\t  if(temp&gt;0) {\n\t    timeprinted=1;\n\t    stat_line_printf(\" %dd\",temp);\n\t    secondsleft2-=temp*(24*3600);\n\t  }\n\t  temp=secondsleft2\/3600;\n\t  if(temp&gt;0) {\n\t    timeprinted=1;\n\t    stat_line_printf(\" %dh\",temp);\n\t    secondsleft2-=temp*3600;\n\t  }\n\t  temp=secondsleft2\/60;\n\t  if(temp&gt;0) {\n\t    timeprinted=1;\n\t    stat_line_printf(\" %dm\",temp);\n\t    secondsleft2-=temp*60;\n\t  }\n\t  temp=secondsleft2;\n\t  if(!timeprinted) {\n\t    stat_line_printf(\" %d seconds\",temp);\n\t  }\n\n#ifdef STAT_LINE_READY\n\n\t  long int secondsend=(int)secondsstart+((((double)secondsnow-secondsstart)\/c)*CLIM);\n\n\t  \/\/ print end date if different7\n\t  \n\t  stat_line_printf(\", ready at\");\n\t  strftime(timebuf,sizeof(timebuf),DATEFORMAT,\n\t\t   localtime((time_t *)&amp;secondsend));\n\t  strftime(timebuf2,sizeof(timebuf2),DATEFORMAT,\n\t\t   localtime((time_t *)&amp;secondsnow));\n\t  if(strcmp(timebuf,timebuf2)) {\n\t    stat_line_printf(\" %s\",timebuf);\n\t  }\n\n\t  \/\/ print end time\n\t  \n\t  strftime(timebuf,sizeof(timebuf),TIMEFORMAT,\n\t\t   localtime((time_t *)&amp;secondsend));\n\t  stat_line_printf(\" %s\",timebuf);\n#endif\n\n\t}\n\n\tstat_line_end();\n\t\n\t\/\/ do the work\n\t\n#ifdef STAT_LINE_ANIM\n\tunsigned char cursor&#91;4] = { '|', '\/', '-', '\\\\' };\n\n\tfprintf(stderr,\" \");\n#endif\n\tfor(d=0;d&lt;DLIM;d++) {\n#ifdef STAT_LINE_ANIM\n\t  secs=time(NULL)%sizeof(cursor);\n\t  if(prev_secs!=secs) {\n\t    if(prev_secs!=-1) \n\t      crs=(crs+1)%sizeof(cursor);\n\t    fprintf(stderr,\"\\b%c\",cursor&#91;crs]);\n\t    fflush(stderr);\n\t    prev_secs=secs;\n\t  }\n#endif\n\t  if(input==INPUT_RESSU) \/\/ ressu prod\n\t    ressu_genbytes(sizeof(buffer),buffer);\n\t  else if(input==INPUT_DEBUG) \/\/ ressu debug\n\t    ressu_genbytes_debug(sizeof(buffer),buffer);\n\t  else if(input==INPUT_FAST) \/\/ ressu fast\n\t    ressu_genbytes_fast(sizeof(buffer),buffer);\n\t  else if(input==INPUT_SINGLE) \/\/ ressu single\n\t    ressu_genbytes_single(sizeof(buffer),buffer);\n#ifdef FORT\n\t  else if(input==INPUT_FORT) \/\/ ressu fort\n\t    fort_random_data(sizeof(buffer),buffer);\n\t  else if(input==INPUT_FORTXOR) \/\/ ressu fort\n\t    fort_random_data_xor(sizeof(buffer),buffer);\n#endif\n\t  else if(input==INPUT_URANDOM) \/\/ urandom\n\t    readfile_xor(sizeof(buffer),buffer,urandomfilename);\n#ifdef USE_RANDOM\n\t  else if(input==INPUT_RANDOM) \/\/ random\n\t    readfile_xor(sizeof(buffer),buffer,randomfilename);\n#endif\n\t  \n#ifdef WRITE_SAMPLE\n\t  fwrite(buffer,1,sizeof(buffer),fp1);\n#endif\n\t} \/\/ for(d=0;\n#ifdef STAT_LINE_ANIM\n\tfprintf(stderr,\"\\b \\b\");\n\tprev_secs=-1;\n#endif\n      }\n      fclose(fp1);\n    } \/\/ if((fp1=fopen\n\n    \/\/ remove last status line\n    \n    stat_line_begin();\n    stat_line_printf(\"Done!\");\n    stat_line_end();\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n}\n\n#include &lt;sys\/ioctl.h&gt; \/\/ for TIOCGWINSZ\n\n#define aDEBUG50 2\n\n#define aDEBUG71 2\n\nvoid call_main(char *);\n\n#define aCALL_MAIN 2\n\n#define aDEBUG63 2\n\n#ifdef CALL_MAIN\n\n#define DEBUG99 2\n\nint main2(int argc, char *argv&#91;]);\n\nvoid call_main(char *cmd)\n{\n  int size, round, count, chars;\n  unsigned char *p, *q, *argmem,*params;\n  char **argv;\n\n  size = 0;\n\n  for(round = 0; round &lt; 2; round++) {\n    count = 0;\n    p = cmd;\n    while(*p != '\\0') {\n      while(*p == ' ' || *p == '\\t')\n\tp++;\n      q = p;\n      chars = 0;\n      while(*p != ' ' &amp;&amp;  *p != '\\t' &amp;&amp; *p != '\\0') {\n\tp++;\n\tchars++;\n      }\n      if(round == 0) \/\/ calculate size &amp; alloc\n\tsize += chars + 1 + sizeof(char *);\n      else { \/\/ move parameters to arg area\n\tstrncpy(params, q, chars);\n\t*(argv+count) = params;\n\tparams += (chars+1);\n      }\n      count++;\n    }\n    if(round == 0) { \/\/ allocate\n      size += sizeof(char *); \/\/ ending NULL\n      argmem = malloc(size);\n      argv = (char **)argmem;\n      params = argmem + sizeof(char *) * (count+1);\n    }\n  }\n\n  *(argv+count) = NULL; \/\/ ending NULL\n\n#ifdef DEBUG99\n  \n  fprintf(stdout, \"size:%d,\", size);\n  fprintf(stdout, \" argmem:\");\n  for(int c = 0; c &lt; size; c++) {\n    if(c &gt; 0 &amp;&amp; c%8 == 0)\n      fprintf(stdout, \"|\");\n    if(*(argmem+c) == '\\\\')\n      fprintf(stdout, \"\\\\\\\\\");\n    if(isprint(*(argmem+c)))\n      fprintf(stdout, \"%c\", *(argmem+c));\n    else\n      fprintf(stdout, \"\\\\%02x\", *(argmem+c));\n  }\n  fprintf(stdout, \"\\n\");\n\n#endif \/\/ #ifdef DEBUG99\n\n  main2(count, argv);\n}\n\nint main(int argc, char *argv&#91;])\n{\n  int first;\n  char buffer&#91;1024];\n\n  first=1;\n  buffer&#91;0]='\\0';\n  for(int c=0;c&lt;argc;c++) {\n    if(!first)\n      strcat(buffer,\" \");\n    strcat(buffer,argv&#91;c]);\n    first=0;\n  }\n#ifdef DEBUG99\n  fprintf(stdout,\"main: cmd \\\"%s\\\"\\n\",buffer);\n#endif\n  \n  call_main(buffer);\n}\n\n#endif \/\/ #ifdef CALL_MAIN\n\n#ifdef CALL_MAIN\n\nint main2(int argc, char *argv&#91;])\n{\n#ifdef DEBUG99\n  fprintf(stdout,\"main2args:\");  \n  for(int c=0;c&lt;argc;c++) {\n    fprintf(stdout,\" %d:\\\"%s\\\"\",c,argv&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n#endif \/\/ #ifdef DEBUG99\n\n#else \/\/ #ifdef CALL_MAIN\n\nint main(int argc, char *argv&#91;])\n{\n#endif \/\/ #ifdef CALL_MAIN\n  \n  int c, d, status=0;\n\n  procname=argv&#91;0];\n  limit=0;\n\n#ifdef NOTUSED\n  for(c=0;c&lt;100000000;c++) {\n    fprintf(stdout,\"%d %f %f\\n\",c,log10((double)c),log10((double)c)+1);\n  }\n#endif\n  gent_clear();\n  ressut_clear();\n\n  clockbytes=0;\n  for(d=0;d&lt;1024;d++)\n    periods&#91;d]=0;\n\n  \n#ifdef DEBUG63\n  \n  \/\/unsigned long l=(unsigned long)ressu_gen_limit((unsigned long)10001);\n  \/\/for(;l&lt;=0x3ffffffffff;l*=2) {\n  unsigned long l=1;\n  for(;l&lt;=0x3ffffffffff;l*=2) {\n    if(l==0x9d || l==0x9e || l==0x9f)\n      continue;\n    unsigned char buffer&#91;32];\n    unsigned long code;\n    codetoutf8(buffer, l);\n    utf8tocode(&amp;code, buffer);\n    if(code!=l) {\n      fprintf(stdout,\"%s: codetoutf8 and utf8tocode does not match\",procname);\n      fprintf(stdout,\", l:%ld\",l);\n      fprintf(stdout,\", code:%ld\",code);\n      fprintf(stdout,\"\\n\");\n      exit(1);\n    }\n  }\n#endif\n  \n#ifdef USE_TIMER\n  int timer=0;\n  double timerstart;\n#endif  \n\n  \/\/ look thru command line parameters\n  \n  for(c=1;c&lt;argc;c++) {\n    if(!strncmp(\"-\",argv&#91;c],1)) {\n      if(!strcmp(\"--lineno\",argv&#91;c])) {\n\tslineno = !slineno;\n\n      } else if(!strcmp(\"--crlf\",argv&#91;c])) {\n\tscrlf = !scrlf;\n\tslineno = 0;\n\n      } else if(!strcmp(\"--quiet\",argv&#91;c])) {\n\tquiet = !quiet;\n\n      } else if(!strcmp(\"--stats\",argv&#91;c]) ||\n\t!strcmp(\"--stat\",argv&#91;c])) {\n\tstats = !stats;\n\n      } else if(!strcmp(\"--rand\",argv&#91;c])) {\n\tdigits = \"0123456789\";\n\tsspace = 2;\n\tsnewline = 5;\n\tslineno = 1;\n\twords = 10;\n\tchars = 0;\n\tlimit = 100000;\n\t\/\/size=5;\n\t\/\/lines=20000;\n\t\n      } else if(!strncmp(\"--space\",argv&#91;c],7)) {\n\tif(*(argv&#91;c]+7)!='\\0' &amp;&amp; atoi(argv&#91;c]+7)&gt;1) {\n\t  sspace = atoi(argv&#91;c]+7);\n\t} else if(c+1&lt;argc &amp;&amp; atoi(argv&#91;c+1])&gt;1) {\n\t  sspace = atoi(argv&#91;c+1]);\n\t  c++;\n\t} else {\n\t  sspace = !sspace;\n\t}\n\n      } else if(!strncmp(\"--newline\",argv&#91;c],9)) {\n\tif(*(argv&#91;c]+9)!='\\0' &amp;&amp; atoi(argv&#91;c]+9)&gt;0) {\n\t  snewline = atoi(argv&#91;c]+9);\n\t} else if(c+1&lt;argc &amp;&amp; atoi(argv&#91;c+1])&gt;0) {\n\t  snewline = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\n      } else if(!strcmp(\"--zero\",argv&#91;c])) {\n\tzero = !zero;\n\n      } else if(!strcmp(\"--sort\",argv&#91;c])) {\n\tsort = !sort;\n\tif(sspace == 0)\n\t  sspace = 1;\n\t\t\n      } else if(!strcmp(\"--unique\",argv&#91;c])) {\n\tunique =! unique;\n\tif(sspace == 0)\n\t  sspace = 1;\n\t\t\n      } else if(!strcmp(\"--lotto\",argv&#91;c])) {\n\tsort = !sort;\n\tif(sspace==0)\n\t  sspace = 1;\n\t\/\/sort = 1;\n\t\/\/unique = 1;\n\n      } else if(!strcmp(\"--sample\",argv&#91;c])) {\n\tsample = !sample;\n\t\n      } else if(!strcmp(\"--copyright\",argv&#91;c]) ||\n\t !strcmp(\"--version\",argv&#91;c])) {\n\tnewressu_version();\n#ifdef SHA256\n\tunsigned char filedigest&#91;HashLen];\n\tnewressu_file_digest(\"\/proc\/self\/exe\", filedigest);\n\tfprintf(stderr,\"\\nsha256: \");\n\tfor(int c = 0;c &lt; HashLen; c++) {\n\t  fprintf(stderr,\"%02x\", filedigest&#91;c]);\n\t}\n#endif\n\n\tfprintf(stderr,\"\\n\\n\");\n\thelp = 1;\n\t\n      } else if(!strncmp(\"--lim\",argv&#91;c],5)) {\n\tif(*(argv&#91;c]+5)!='\\0') {\n\t  in_word(&amp;limit, digits, argv&#91;c]+5);\n\t} else if(c+1&lt;argc) {\n\t  in_word(&amp;limit, digits, argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(sspace&lt; 1 ) \/\/ 23.6.2021\n\t  sspace = 1;\n\n      } else if(!strncmp(\"-s\",argv&#91;c],2)) {\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  size = atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  size = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tlimit = 0; \/\/ 23.6.2021\n\n      } else if(!strncmp(\"--bits\",argv&#91;c],6)) {\n\tif(*(argv&#91;c]+6)!='\\0') {\n\t  ressu_bits1_needed = atoi(argv&#91;c]+6);\n\t} else if(c+1&lt;argc) {\n\t  ressu_bits1_needed = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\t\n\n      } else if(!strncmp(\"--bytes\",argv&#91;c],7)) {\n\tif(*(argv&#91;c]+7)!='\\0') {\n\t  ressut_bytes = atoi(argv&#91;c]+7);\n\t} else if(c+1&lt;argc) {\n\t  ressut_bytes = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\t\n\n      } else if(!strncmp(\"-w\",argv&#91;c],2)) { \/\/ words per line\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  words = atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  words = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(words &lt; 1)\n\t  words = 1;\n\tchars = 0;\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"-c*\",argv&#91;c],3)) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\twords = 0;\n#ifdef DEBUG71\n\tfprintf(stdout,\"screencolumns:%d\\n\",chars);\n#endif\n\n      } else if(!strncmp(\"-l*\",argv&#91;c],3)) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tlines = w.ws_row-1;\n#ifdef DEBUG71\n\tfprintf(stdout,\"screenlines:%lld\\n\",lines);\n#endif\n\n      } else if(!strncmp(\"--screen\",argv&#91;c],8)) {\n\tstruct winsize w;\n\tioctl(0, TIOCGWINSZ, &amp;w);\n\tchars = w.ws_col;\n\tlines = w.ws_row-1;\n\twords = 0;\n\tscreen = 1;\n#ifdef DEBUG71\n\tfprintf(stdout,\"screencolumns:%d\",chars);\n\tfprintf(stdout,\" screenlines:%lld\\n\",lines);\n#endif\n\t\n      } else if(!strncmp(\"-c\",argv&#91;c],2)) {  \/\/ characters per line\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  chars = atoi(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  chars = atoi(argv&#91;c+1]);\n\t  c++;\n\t}\n\tif(chars &lt; 1)\n\t  chars = 72;\n\twords = 0;\n\tscreen = 0;\n\t\n      } else if(!strncmp(\"-l\",argv&#91;c],2)) { \/\/ lines\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  lines = atoll(argv&#91;c]+2);\n\t} else if(c+1&lt;argc) {\n\t  lines = atoll(argv&#91;c+1]);\n\t  c++;\n\t}\n\tscreen = 0;\n\t\n      } else if(!strcmp(\"-x\",argv&#91;c])) {\n\tdigits = \"0123456789abcdef\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 16;\n\n      } else if(!strcmp(\"-X\",argv&#91;c])) {\n\tdigits = \"0123456789ABCDEF\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 4;\n\ttype = 16;\n\n      } else if(!strcmp(\"-d\",argv&#91;c])) {\n\tdigits = \"0123456789\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 5;\n\ttype = 10;\n\n      } else if(!strcmp(\"-o\",argv&#91;c])) {\n\tdigits = \"01234567\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 3;\n\ttype = 8;\n\n      } else if(!strcmp(\"-b\",argv&#91;c])) {\n\tdigits = \"01\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 2;\n\n      } else if(!strcmp(\"-1\",argv&#91;c])) {\n\tdigits=\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"-11\",argv&#91;c])) {\n\tdigits=\n\t  \"0123456789\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 10;\n\n      } else if(!strcmp(\"-12\",argv&#91;c])) {\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\n      } else if(!strcmp(\"-13\",argv&#91;c])) {\n\tdigits=\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"-2\",argv&#91;c])) {\n\tdigits=\n\t  \"0123456789\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\" \\\n\t  \"_-\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"-3\",argv&#91;c])) { \/\/ 9.5.2021 JariK\n\tdigits=\n\t  \"!\\\"#$%&amp;'()*+,-.\/0123456789:;&lt;=&gt;?@\" \\\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ&#91;\\\\]^_`\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz{|}~\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--dnk\",argv&#91;c]) || \/\/ Danish alphabet\n\t\t!strcmp(\"--nor\",argv&#91;c])) { \/\/ Norwegian alphabet\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--fin\",argv&#91;c]) || \/\/ Finnish alphabet\n\t\t!strcmp(\"--swe\",argv&#91;c])) { \/\/ Swedish alphabet\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--rus\",argv&#91;c])) { \/\/ Russian alphabet\n\tdigits=\n\t  \"\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\" \\\n\t  \"\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--est\",argv&#91;c])) { \/\/ Estonian alphabet\n\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRS\u0160Z\u017dTUVW\u00d5\u00c4\u00d6\u00dcXY\" \\\n\t  \"abcdefghijklmnopqrs\u0161z\u017etuvw\u00f5\u00e4\u00f6\u00fcxy\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n  \n      } else if(!strcmp(\"--ltu\",argv&#91;c])) { \/\/ Lithuanian alphabet\n\tdigits=\n\t  \"A\u0104BC\u010cDE\u0118\u0116FGHI\u012eYJKLMNOPRS\u0160TU\u0172\u016aVZ\u017d\" \\\n\t  \"a\u0105bc\u010dde\u0119\u0117fghi\u012fyjklmnoprs\u0161tu\u0173\u016bvz\u017e\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--lva\",argv&#91;c])) { \/\/ Latvian alphabet\n\tdigits=\n\t  \"A\u0100BC\u010cDE\u0112FG\u0122HI\u012aJK\u0136L\u013bMN\u0145OPRS\u0160TU\u016aVZ\u017d\" \\\n\t  \"a\u0101bc\u010dde\u0113fg\u0123hi\u012bjk\u0137l\u013cmn\u0146oprs\u0161tu\u016bvz\u017e\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--fra\",argv&#91;c]) \/\/ French alphabet\n\t\t||!strcmp(\"--gbr\",argv&#91;c]) \/\/ Great Britain alphabet\n\t\t||!strcmp(\"--usa\",argv&#91;c]) \/\/ United States alphabet\n\t\t||!strcmp(\"--ita\",argv&#91;c]) \/\/ Italian alphabet\n\t\t||!strcmp(\"--eng\",argv&#91;c]) \/\/ English alphabet\n\t\t) {\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--deu\",argv&#91;c])) { \/\/ Deutsch alphabet\n\tdigits=\n\t  \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u1e9e\" \\\n\t  \"abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00fc\u00df\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--grc\",argv&#91;c])) { \/\/ Greek alphabet\n\tdigits=\n\t  \"\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\" \\\n\t  \"\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 8;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--jp\",argv&#91;c])) { \/\/ all Japanese alphabets\n\n\tdigits = NULL;\n\tdigits_add_string(&amp;digits,\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\");\n\tdigits_add_string(&amp;digits,\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\");\n\tdigits_add_limits(&amp;digits,0x4e00,0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n\t\n      } else if(!strcmp(\"--jp1\",argv&#91;c]) \/\/ Japanese hiragana alphabet\n\t\t||!strcmp(\"--hir\",argv&#91;c])) { \/\/ Japanese hiragana alphabet\n\tdigits=\n\t    \"\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048\u3049\u304a\u304b\u304c\u304d\u304e\u304f\"\n\t  \"\u3050\u3051\u3052\u3053\u3054\u3055\u3056\u3057\u3058\u3059\u305a\u305b\u305c\u305d\u305e\u305f\"\n\t  \"\u3060\u3061\u3062\u3063\u3064\u3065\u3066\u3067\u3068\u3069\u306a\u306b\u306c\u306d\u306e\u306f\"\n\t  \"\u3070\u3071\u3072\u3073\u3074\u3075\u3076\u3077\u3078\u3079\u307a\u307b\u307c\u307d\u307e\u307f\"\n\t  \"\u3080\u3081\u3082\u3083\u3084\u3085\u3086\u3087\u3088\u3089\u308a\u308b\u308c\u308d\u308e\u308f\"\n\t  \"\u3090\u3091\u3092\u3093\u3094\u3095\u3096\";\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--jp2\",argv&#91;c]) \/\/ Japanese katakana alphabet\n\t\t||!strcmp(\"--kat\",argv&#91;c])) {  \/\/ Japanese katakana alphabet\n\tdigits=\n\t  \"\u30a0\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\"\n\t  \"\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9\u30ba\u30bb\u30bc\u30bd\u30be\u30bf\"\n\t  \"\u30c0\u30c1\u30c2\u30c3\u30c4\u30c5\u30c6\u30c7\u30c8\u30c9\u30ca\u30cb\u30cc\u30cd\u30ce\u30cf\"\n\t  \"\u30d0\u30d1\u30d2\u30d3\u30d4\u30d5\u30d6\u30d7\u30d8\u30d9\u30da\u30db\u30dc\u30dd\u30de\u30df\"\n\t  \"\u30e0\u30e1\u30e2\u30e3\u30e4\u30e5\u30e6\u30e7\u30e8\u30e9\u30ea\u30eb\u30ec\u30ed\u30ee\u30ef\"\n\t  \"\u30f0\u30f1\u30f2\u30f3\u30f4\u30f5\u30f6\u30f7\u30f8\u30f9\u30fa\u30fb\u30fc\u30fd\u30fe\u30ff\";\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cn\",argv&#91;c]) \/\/ Chinese alphabet \n\t\t||!strcmp(\"--jp3\",argv&#91;c]) \/\/ Japanese kanji alphabet\n\t\t||!strcmp(\"--kan\",argv&#91;c])) { \/\/ Japanese kanji alphabet\n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits,0x4e00,0x9fef);\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--kor\",argv&#91;c])) { \/\/ Korean alphabet \n\n\tdigits = NULL;\n\tdigits_add_limits(&amp;digits,0xac00,0xd7a3);   \/\/ Hangul Syllables (AC00\u2013D7A3)\n\t\/\/digits_add_limits(&amp;digits,0x1100,0x11ff); \/\/ Hangul Jamo (1100\u201311FF)\n\t\/\/digits_add_limits(&amp;digits,0x3130,0x318f); \/\/ Hangul Compatibility Jamo (3130\u2013318F)\n\t\/\/digits_add_limits(&amp;digits,0xa960,0xa97f); \/\/ Hangul Jamo Extended-A (A960\u2013A97F)\n\t\/\/digits_add_limits(&amp;digits,0xd7b0,0xd7ff); \/\/Hangul Jamo Extended-B (D7B0\u2013D7FF)\n\n\tdigitsext = digits;\n\tcharspaces = 0;\n\tcharwidth = 2;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--got\",argv&#91;c])) { \/\/ Greek alphabet                                                                                                                          \n        digits=\n          \"\ud800\udf30\ud800\udf31\ud800\udf32\ud800\udf33\ud800\udf34\ud800\udf35\ud800\udf36\ud800\udf37\ud800\udf38\ud800\udf39\ud800\udf3a\ud800\udf3b\ud800\udf3c\ud800\udf3d\ud800\udf3e\ud800\udf3f\"\n          \"\ud800\udf40\ud800\udf41\ud800\udf42\ud800\udf43\ud800\udf44\ud800\udf45\ud800\udf46\ud800\udf47\ud800\udf48\ud800\udf49\ud800\udf4a\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n        size = 8;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cards\",argv&#91;c])) {\n\tdigits=\n\t  \"\ud83c\udca1\ud83c\udca2\ud83c\udca3\ud83c\udca4\ud83c\udca5\ud83c\udca6\ud83c\udca7\ud83c\udca8\ud83c\udca9\ud83c\udcaa\ud83c\udcab\ud83c\udcad\ud83c\udcae\" \\\n\t  \"\ud83c\udcb1\ud83c\udcb2\ud83c\udcb3\ud83c\udcb4\ud83c\udcb5\ud83c\udcb6\ud83c\udcb7\ud83c\udcb8\ud83c\udcb9\ud83c\udcba\ud83c\udcbb\ud83c\udcbd\ud83c\udcbe\" \\\n\t  \"\ud83c\udcc1\ud83c\udcc2\ud83c\udcc3\ud83c\udcc4\ud83c\udcc5\ud83c\udcc6\ud83c\udcc7\ud83c\udcc8\ud83c\udcc9\ud83c\udcca\ud83c\udccb\ud83c\udccd\ud83c\udcce\" \\\n\t  \"\ud83c\udcd1\ud83c\udcd2\ud83c\udcd3\ud83c\udcd4\ud83c\udcd5\ud83c\udcd6\ud83c\udcd7\ud83c\udcd8\ud83c\udcd9\ud83c\udcda\ud83c\udcdb\ud83c\udcdd\ud83c\udcde\";\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--cardsuits\",argv&#91;c])) {\n\tdigits=\n\t  \"\u2660\u2661\u2662\u2663\u2664\u2665\u2666\u2667\";\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--chess\",argv&#91;c])) {\n\tdigits=\n\t  \"\u2654\u2655\u2656\u2657\u2658\u2659\u265a\u265b\u265c\u265d\u265e\u265f\";\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\t\n      } else if(!strcmp(\"--pattern1\",argv&#91;c])) {\n\tdigits=\n\t  \"\u258c\u2599\u2584\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern2\",argv&#91;c])) {\n\tdigits=\n\t  \"\u25dc\u25dd\u25de\u25df\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern3\",argv&#91;c])) {\n\tdigits=\n\t  \"\\\\\/\";\n\tcharspaces = 0;\n\tcharwidth = 1;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern4\",argv&#91;c])) {\n\tdigits=\n\t  \"\u25f8\u25f9\u25fa\u25ff\";\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--pattern5\",argv&#91;c])) {\n\tdigits=\n\t  \"\u25a7\u25a8\";\n\tcharspaces = 1;\n\tcharwidth = 2;\n\tsize = 1;\n\ttype = 0;\n\n      } else if(!strcmp(\"--isalnum\",argv&#91;c]) || \/\/ 9.5.2021 JariK\n\t        !strcmp(\"--isalpha\",argv&#91;c]) ||\n\t        !strcmp(\"--isdigit\",argv&#91;c]) ||\n\t        !strcmp(\"--isgraph\",argv&#91;c]) ||\n\t        !strcmp(\"--islower\",argv&#91;c]) ||\n\t        !strcmp(\"--isprint\",argv&#91;c]) ||\n\t        !strcmp(\"--ispunct\",argv&#91;c]) ||\n\t        !strcmp(\"--isupper\",argv&#91;c]) ||\n\t\t!strcmp(\"--isxdigit\",argv&#91;c])) {\n\tunsigned char *p=digitstemp;\n\tfor(d=0;d&lt;256;d++) {\n\t  if((!strcmp(\"--isalnum\",argv&#91;c]) &amp;&amp; isalnum(d)) ||\n\t     (!strcmp(\"--isalpha\",argv&#91;c]) &amp;&amp; isalpha(d)) ||\n\t     (!strcmp(\"--isdigit\",argv&#91;c]) &amp;&amp; isdigit(d)) ||\n\t     (!strcmp(\"--isgraph\",argv&#91;c]) &amp;&amp; isgraph(d)) ||\n\t     (!strcmp(\"--islower\",argv&#91;c]) &amp;&amp; islower(d)) ||\n\t     (!strcmp(\"--isprint\",argv&#91;c]) &amp;&amp; isprint(d)) ||\n\t     (!strcmp(\"--ispunct\",argv&#91;c]) &amp;&amp; ispunct(d)) ||\n\t     (!strcmp(\"--isupper\",argv&#91;c]) &amp;&amp; isupper(d)) ||\n\t     (!strcmp(\"--isxdigit\",argv&#91;c]) &amp;&amp; isxdigit(d))) {\n\t    *p++=d;\n\t  }\n\t}\n\t*p='\\0';\n\tdigits = digitstemp;\n\tsize = 8;\n\ttype = 0;\n\n      } else if(!strncmp(\"-i\",argv&#91;c],2)) {\n\tdigits=NULL;\n\tif(*(argv&#91;c]+2)!='\\0') {\n\t  digits = argv&#91;c]+2;\n\t} else if(c+1 &lt; argc) {\n\t  digits = argv&#91;c+1];\n\t  c++;\n\t}\n\tif(digits==NULL || utf8characters(digits)&lt;2) {\n\t  fprintf(stderr,\"%s: not enough digits \\\"%s\\\"\\n\",procname,argv&#91;c]);\n\t  help = 1;\n\t}\n\tsize = 1;\n\n#ifdef USE_TIMER\n      } else if(!strcmp(\"--timer\",argv&#91;c])) {\n\ttimer=1;\n\n#endif\n      } else if(!strcmp(\"--ressu\",argv&#91;c])) {\n\tinput = INPUT_RESSU;\n\n      } else if(!strcmp(\"--debug\",argv&#91;c])) {\n\tinput = INPUT_DEBUG;\n\n      } else if(!strcmp(\"--fast\",argv&#91;c])) {\n\tinput = INPUT_FAST;\n\n      } else if(!strcmp(\"--single\",argv&#91;c])) {\n\tinput = INPUT_SINGLE;\n\n#ifdef FORT\n      } else if(!strcmp(\"--fort\",argv&#91;c])) {\n\tinput = INPUT_FORT;\n\n      } else if(!strcmp(\"--fortxor\",argv&#91;c])) {\n\tinput = INPUT_FORTXOR;\n\n      } else if(!strcmp(\"--fortverbose\",argv&#91;c])) {\n\tfort_verbose = !fort_verbose;\n\n      } else if(!strcmp(\"--fortuseweb\",argv&#91;c])) {\n\tfort_use_web = !fort_use_web;\n\t\n#endif\n      } else if(!strcmp(\"--urandom\",argv&#91;c])) {\n\tinput = INPUT_URANDOM;\n\n#ifdef USE_RANDOM\n      } else if(!strcmp(\"--random\",argv&#91;c])) {\n\tinput = INPUT_RANDOM;\n\n#endif\n      } else {\n\tfprintf(stderr,\"%s: invalid option %s\\n\",procname,argv&#91;c]);\n\tstatus = 1;\n\thelp = 1;\n      }\n    } else {\n      help = 1;\n\n    } \/\/ if(!strncmp\n  } \/\/ for(c=0\n\n  if(size == 0)\n    size = 1;\n  else if(size &gt; 1024)\n    size = 1024;\n  if(lines &lt; 1)\n    lines = 1;\n\n#ifdef USE_TIMER\n  timerstart=getseconds();\n#endif\n  \n  digitscount = utf8characters(digits);\n  characterlengths = utf8lengths(digits);\n\n#ifdef FORT\n  if(input == INPUT_FORT ||\n     input == INPUT_FORTXOR ) {\n    strcpy(fort_random_file, \"newressufort.rnd\");\n    \/\/fort_verbose=0;\n    fort_init();\n  }\n#endif\n  \n  if(sample) {\n    dump_sample();\n    exit(status);\n  } \/\/ if(sample)\n\n  \/\/ get linenumber length in digits\n\n  plinesdigits = line_number_length();\n\n  \/\/ get data length in digits\n\n  if(limit != 0) {\n    unsigned char wordbuf&#91;128];\n    out_word(sizeof(wordbuf), wordbuf, digits, limit-1);\n    size = utf8characters(wordbuf);\n  }\n\n  pchars = 0;\n  pwords = 0;\n  int linew = 0;\n\n  \/\/ in beginning of line, count printed line number\n      \n  if(!quiet &amp;&amp; slineno) {\n    sprintf(linenobuf,\"%0*llu\", plinesdigits, plines);\n    pchars += strlen(linenobuf);\n    pchars++;\n  }\n\n  \/\/ count words\n  \n  while((chars &gt; 0 &amp;&amp; pchars+size*charwidth+calc_spaces() &lt;= chars) ||\n\t(words &gt; 0 &amp;&amp; pwords &lt; words)) {\n    \n    linew++;\n\n#ifdef DEBUG50\n    fprintf(stdout,\"spaces:%d\", calc_spaces());\n#endif\n    \n    pchars += calc_spaces();\n    pchars += (size*charwidth);\n    pwords++;\n\n#ifdef DEBUG50\n    fprintf(stdout,\", chars:%d\", chars);\n    fprintf(stdout,\", pchars:%d\", pchars); \n    fprintf(stdout,\", words:%d\", words);\n    fprintf(stdout,\", pwords:%d\", pwords);  \n    fprintf(stdout,\"\\n\");\n#endif\n  }\n\n  \/\/ one data word needed\n  \n  if(linew &lt; 1)\n    linew = 1;\n\n  unsigned long wordvalues=1, wordvaluesold;\n\n  for(c = 0; c &lt; size; c++) {\n    wordvaluesold = wordvalues;\n    wordvalues *= digitscount;\n    if(wordvalues \/ digitscount != wordvaluesold) {\n      wordvalues = 0;\n      break;\n    }\n  }\n  \n  if(limit &gt; 0) {\n    if(sort==1 &amp;&amp; limit-!zero &lt; words) {\n      fprintf(stderr,\"%s: limit is less than words (zero)\", procname);\n      fprintf(stderr,\", limit:%lu\", limit);\n      fprintf(stderr,\", words:%d\", words);\n      fprintf(stderr,\", zero:%d\", zero);\n      fprintf(stderr,\"\\n\");\n      \n      help = 1;\n      lines = 0;\n    }\n  } else {\n    if(sort == 1 &amp;&amp; size &gt; 0 &amp;&amp; wordvalues &gt; 0 &amp;&amp; wordvalues &lt; linew) {\n      fprintf(stderr,\"%s:\", procname);\n      fprintf(stderr,\" digits is less than calculated words\");\n      fprintf(stderr,\", digits:%d(%lu)\", digitscount, wordvalues);\n      fprintf(stderr,\", words:%d\\n\", linew);\n      help = 1;\n      lines = 0;\n    }\n  }\n\n  \/\/ \"small\" words as single ressu_gen_limit() call\n  \n  if(limit == 0 &amp;&amp; wordvalues &gt; 0)\n    limit = wordvalues;\n\n#ifdef DEBUG51\n  unsigned char buffer10&#91;10];\n  if(type==2)\n    sprintf(buffer10,\"%2lx\",limit-1);\n  else if(type==8)\n    sprintf(buffer10,\"%2lo\",limit-1);\n  else if(type==10)\n    sprintf(buffer10,\"%2ld\",limit-1);\n  else if(type==16)\n    sprintf(buffer10,\"%2lx\",limit-1);\n  else\n    sprintf(buffer10,\"%2ld\",limit-1);\n  limitsize=strlen(buffer10);\n#endif  \n  \n  if(stats) {\n    fprintf(stdout,\"randomsource: %s\", randomgen&#91;input]);\n    fprintf(stdout,\", size: %d\", size);\n    fprintf(stdout,\", linew: %d\", linew);\n    fprintf(stdout,\", pchars: %d\", pchars);\n    fprintf(stdout,\", pwords: %d\", pwords);\n    fprintf(stdout,\", tchars: %llu\", (unsigned long long)size*linew*lines);\n    fprintf(stdout,\", digitscount: %d\", digitscount);\n    if(wordvalues &gt; 0)\n      fprintf(stdout,\", wordvalues: %lu\", wordvalues);\n    if(limit &gt; 0) {\n      fprintf(stdout,\", limit: %lu\", limit);\n#ifdef DEBUG51\n      fprintf(stdout,\", type: %d\",type);\n      fprintf(stdout,\", limitsize%d: %d\",type,limitsize);\n#endif\n    }\n    fprintf(stdout,\"\\n\");\n  }\n  \n  if(help) {\n    struct helpline {\n      char *command;\n      char *text;\n    } helplines&#91;] = {\n      { \"newressu -d\", \"print random decimal digits (default)\" },\n      { \"newressu -o\", \"print octal digits\" },\n      { \"newressu -x\", \"print hexadecimal digits\" },\n      { \"newressu -b\", \"print binary digits\" },\n      { \"newressu -d --space\", \"print decimal digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -b --space\", \"print binary digits, with spaces between \\\"words\\\"\" },\n      { \"newressu -d -l30\", \"print decimal digits, 30 lines\" },\n      { \"newressu -d -l30 --lineno\", \"print decimal digits, 30 lines, no linenumbers\"  },\n      { \"newressu --rand\", \"print numbers in rand style listing\"  },\n      { \"newressu --space 2\", \"print numbers in 2 number groups\"  },\n      { \"newressu --newline 5\", \"print numbers in 5 line groups\"  },\n      { \"newressu -l*\", \"fill all screen lines\"  },\n      { \"newressu -c*\", \"fill all screen columns\"  },\n      { \"newressu --screen\", \"fill screen columns and lines\"  },\n      { \"newressu -d -c128\", \"print decimal digits, 128 characters per line\"  },\n      { \"newressu -d --lim10\", \"print decimal numbers between 0-9\" },\n      { \"newressu -d --lim10 -x\",\"print hexadecimal numbers with decimal limit\" },\n      { \"newressu -d -s10 --space\",\"print decimal numbers with spaces and wordsize 10\" },\n      { \"newressu -d --space --zero --lim7\",\"print rollings of dice (1-6)\" },\n      { \"newressu -b -s1 --space\",\"print throws of coin (0,1)\" },\n      { \"newressu -d --lim41 -w7 --zero --lotto\",\"print lotto numbers for finnish lotto 7x(1-40)\" },\n      { \"newressu -d -s5 --sort -w16\",\"print 16 sorted decimal numbers from 0 to 99999\" },\n      { \"newressu --isalnum\", \"print alphanumeric characters\" },\n      { \"newressu --isalpha\", \"print alphabetic characters\" },\n      { \"newressu --isgraph\", \"print printables excluding space\" },\n      { \"newressu --islower\", \"print lowercase characters\" },\n      { \"newressu --ispunct\", \"print punctuation characters\" },\n      { \"newressu --isupper\", \"print uppercase characters\" },\n      { \"newressu -1\", \"print material for passwords\" },\n      { \"newressu --dnk\/--nor\", \"danish\/norwegian alphabet\" },\n      { \"newressu --fin\/--swe\", \"finnish\/norwegian alphabet\" },\n      { \"newressu --rus\", \"russian alphabet\" },\n      { \"newressu --est\", \"estonian alphabet\" },\n      { \"newressu --ltu\", \"lithuanian alphabet\" },\n      { \"newressu --lva\", \"latvian alphabet\" },\n      { \"newressu --fra\/--gbr\/--usa\/--ita\", \"french\/gb\/us\/italian alphabet\" },\n      { \"newressu --deu\", \"deutsch alphabet\" }, \n      { \"newressu --grc\", \"greek alphabet\" }, \n      { \"newressu --jp\", \"japan alphabet (hiragana, katakana, kanji) \" }, \n      { \"newressu --jp1\/--hir\", \"japan alphabet (hiragana) \" }, \n      { \"newressu --jp2\/--kat\", \"japan alphabet (katakana) \" }, \n      { \"newressu --jp3\/--kan\", \"japan alphabet (kanji) \" }, \n      { \"newressu --cn\", \"chinese alphabet\" }, \n      { \"newressu --kor\", \"korean alphabet\" }, \n      { \"newressu --got\", \"gothic alphabet\" }, \n      { \"newressu --cards\", \"playing cards\" }, \n      { \"newressu --cardsuits\", \"playing card suits\" }, \n      { \"newressu --chess\", \"chess men\" }, \n      { \"newressu -i\u258c\u2599\u2584 \/ --pattern1\", \"print pattern1\" },\n      { \"newressu -i\\\\\\\\\/ \/ --pattern2\", \"print pattern2\" },\n      { \"newressu --ressu\", \"use randomness from ressu (default)\" },\n      { \"newressu --debug\", \"use randomness from debugging ressu\" },\n      { \"newressu --fast\", \"use randomness from fast ressu\" },\n      { \"newressu --single\", \"use randomness from single round of ressu\" },\n#ifdef FORT\n      { \"newressu --fort\", \"use randomness from fort\" },\n#endif\n      { \"newressu --urandom\", \"use randomness from \/dev\/urandom\" },\n#ifdef USE_RANDOM\n      { \"newressu --random\", \"use randomness from \/dev\/random\" },\n#endif\n    };\n    \n    for(c = 0; c &lt; sizeof(helplines) \/ sizeof(helplines&#91;0]); c++) {\n      fprintf(stderr,\"%-50s\", helplines&#91;c].text);\n      fprintf(stderr,\"%-25s\", helplines&#91;c].command);\n      fprintf(stderr,\"\\n\");\n    }\n    for(c = 0; c &lt; chars; c++)\n      fprintf(stdout, \"*\");\n    fprintf(stdout, \"\\n\");\n    if(lines &gt; 1)\n      lines = 1; \/\/ print one line below help as a sample\n  }\n\n  if(lines == 0)\n    exit(status);\n\n  int linecnt = 0;\n  unsigned char *line = NULL;\n  unsigned char wordbuf&#91;1025];\n  \n  for(;;) {\n\n    if(!sort) { \/\/ no sort, no lotto\n\n      pwords = 0;\n\n      while(pwords &lt; linew) {\n\treadword(wordbuf);\n\n\tif(!quiet) {\n\n\t  if(newressu_output) {\n\t    fprintf(stdout, \"\\n\");\n\t    newressu_output = 0;\n\t  }\n\n\t  \/\/ in beginning of line, print line number\n\n\t  print_line_number();\n\t\n\t  \/\/ want to print spaces between \"words\"?\n\n\t  print_spaces();\n\t\n\t  \/\/ print word\n\n\t  print_word(wordbuf);\n\t}\n\n\tpwords++;\n      } \/\/ while(pwords&lt;linew) {\n    } else { \/\/ if(!sort)\n\n      pwords = 0;\n      \n      line_clear(&amp;linecnt, &amp;line);\n\n      \/\/ fetch and save words on this row\n\n      while(pwords &lt; linew) {\n\treadword(wordbuf);\n\n\tif(line_add_string_sort(&amp;linecnt, &amp;line, wordbuf)) {\n\t  pwords++;\n\t}\n      } \/\/ while(pwords&lt;linew) {\n\n      pwords = 0;\n\n      \/\/ print words on this row\n\n      while(pwords &lt; linew) {\n\n\tline_get_string(sizeof(wordbuf), wordbuf, pwords, line);\n\n\tif(!quiet) {\n\n\t  if(newressu_output) {\n\t    fprintf(stdout, \"\\n\");\n\t    newressu_output = 0;\n\t  }\n\t  \n\t  \/\/ in beginning of line, print line number\n\n\t  print_line_number();\n\t\n\t  \/\/ want to print spaces between \"words\"?\n\t\n\t  print_spaces();\n\n\t  \/\/ print word\n\t\n\t  print_word(wordbuf);\n\t}\n\tpwords++;\n      } \/\/ while(pwords&lt;linew) {\n    } \/\/ if(!sort)\n\n    if(!quiet) {\n      fprintf(stdout, \"\\n\");\n    }\n\n    plines++;\n    ptotallines++;\n\n    \/\/ print empty line\n\n    if(!quiet &amp;&amp;\n       snewline &gt; 0 &amp;&amp;\n       plines%snewline == 0) {\n      \/\/ if screenfull printed, use\n      \/\/ total lines (contains also\n      \/\/ empty lines), if not\n      \/\/ screenfull use printed\n      \/\/ lines (without empty lines)\n      if((screen &amp;&amp; ptotallines &lt; lines) ||\n\t (!screen &amp;&amp; plines &lt; lines)) {\n\tfprintf(stdout, \"\\n\");\n\tptotallines++;\n      }\n    }\n\n    newressu_output = 0;\n    \n    \/\/ all needed lines printed?\n\n    if(screen &amp;&amp; snewline &gt; 0 &amp;&amp;\n       ptotallines &gt;= lines)\n      break;\n    if(plines &gt;= lines)\n      break;\n\n  } \/\/ for(;;)\n\n#ifdef USE_TIMER\n  if(timer) {\n    \/\/ run time 1565 seconds, 0.000782 seconds\/line (decimal)\n    \/\/ run time 6538 seconds, 0.003269 seconds\/line (--ch)\n    \/\/ run time 1954 seconds, 0.000977 seconds\/line (--ch digitscount)\n    \/\/ run time 1814 seconds, 0.000907 seconds\/line (--ch digitscount)\n    \/\/ run time 1540 seconds, 0.000770 seconds\/line (decimal)\n    \/\/ run time 2196 seconds, 0.001098 seconds\/line (--got)\n    \/\/ run time 1536 seconds, 0.000768 seconds\/line (decimal)   \n    \/\/ run time 2008 seconds, 0.001004 seconds\/line (--jp)\n    \/\/ run time 2043 seconds, 0.001022 seconds\/line (--jp)\n    double timertook=getseconds()-timerstart;\n    fprintf(stdout,\"run time %f seconds\",\n\t    timertook);\n    fprintf(stdout,\", %lld lines\",\n\t    plines);\n    fprintf(stdout,\", %f useconds\/line\",\n\t    timertook*1000000\/plines);\n    fprintf(stdout,\", %d characters\/line\",\n\t    pwords*size);\n    fprintf(stdout,\", %f useconds\/character\",\n\t    (timertook*1000000\/plines)\/(pwords*size) );\n    fprintf(stdout,\"\\n\");\n  }\n#endif\n  fflush(stdout);\n\n  if(digitsext != NULL)\n    free(digitsext);\n  \n#ifdef FORT\n  if(input == INPUT_FORT ||\n    input == INPUT_FORTXOR) {\n    fort_save();\n  }\n#endif\n  exit(status);\n}\n\n#endif \/\/ MAIN<\/code><\/pre>\n\n\n\n<p>fort.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;time.h&gt;\n#include &lt;ctype.h&gt;\n\n#include &lt;sys\/time.h&gt;\n#include &lt;errno.h&gt;\n\n#include &lt;openssl\/ssl.h&gt;\n\n#include \"sha256.h\"\n#include \"newressu.h\"\n\nextern unsigned char *procname;\nstatic unsigned char *programname = \"fort version 0.52 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2020-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\n\n#define FORT_INTERNAL_EVENTS 2\n\n#define aDEBUG10 2\n#define aDEBUG18 2\n\n#define FORT_XOR_VERSION 2\n#define FORT_ORIGINAL_VERSION 2\n\n#include \"fort.h\"\n\nint fort_events = 1;\nint fort_verbose = 0;\nint fort_use_web=0;\n\n#define DEBUG 2\n#define FORT_MIN_POOL_SIZE 64\nstatic unsigned int fort_internal_events = 1;\nstatic unsigned int fort_internal_event_mode = 1;\n\n#define FORT_USE_WEB 2\n#define FORT_USE_URANDOM 2\n#define aFORT_USE_RANDOM 2\n#define FORT_USE_NEWRESSU_COMMAND 2\n\nunsigned char fort_random_file&#91;128] = \"fort.rnd\";\n\n#ifdef DEBUG10\nstatic int event_id = 0;\nstatic char fort_events_file&#91;128] = \"fortevents.deb\";\n#endif\n\n\/\/ Additional secrets to fort\n\/\/ (Adversary must guess these too)\n\n#define ADDITIONAL_SECRETS 2\n#ifdef ADDITIONAL_SECRETS\nstatic char fort_secret_file&#91;128] = \"fortsecret.rnd\";\nunsigned char *programsecret = \"OHUwiVmwm8HlqNhKxPi9rdt_8lm4jXI8hi-FCntPAQN_UXOyt4s6zQnRo__ySAd1\";  \n#endif\n\n#define FORT_64_POOLS 2\n\n#ifdef FORT_64_POOLS\n#define FORT_POOLS 64\ntypedef unsigned long FORT_COUNTER;\n#else\n#define FORT_POOLS 32\ntypedef unsigned int FORT_COUNTER;\n#endif\n\nvoid fort_mix();\n\n#define aDEBUG6 2\n\nunsigned char cvar&#91;16];\nint cvarsize=0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c=0;++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar)-1;c++);\n\n#ifdef OLD1\n  c=0;\n  while(++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar)-1)\n    c++;\n#endif\n  \n  if(cvarsize&lt;c)\n    cvarsize=c;\n\n#ifdef DEBUG6\n  if(newressu_output==1)\n    fprintf(stdout,\"\\n\");\n  fprintf(stdout,\"cvar      \");\n  for(int d=cvarsize;d&gt;=0;d--) \/\/ in reverse\n    fprintf(stdout,\"%02x\",cvar&#91;d]);\n  newressu_output=1;\n#endif\n}\n\nvoid clearcvar()\n{\n  int c;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n}\n\nvoid hash_update_cvar(HashCtx *hash)\n{\n  hash_update(hash, (unsigned char *)&amp;cvar,\n\t      cvarsize+1);\n\n  inccvar();  \n}\n\nstatic IUTIME gettenths()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec*10 +\n      (int)tv.tv_usec\/100000);\n}\n\nstatic IUTIME getmicroseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec*1000000 +\n      tv.tv_usec);\n}\n\nstatic IUTIME getseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec);\n}\n\nstruct fort_pool {\n  unsigned long length;\n  HashCtx pool;\n};\nstatic struct fort_pool fort_pools&#91;FORT_POOLS];\n\nvoid fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf)\n{\n  while(len&gt;1 &amp;&amp; buf&#91;len-1]==0)\n    len--;\n\n  HashUpdate(&amp;fort_pools&#91;*pool].pool, buf, len);\n  fort_pools&#91;*pool].length+=len; \/\/ (unsigned long)2097152*16384;\n\n#ifdef DEBUG10\n  if(event_id &lt; 65536) {\n    FILE *fp1;\n    if((fp1=fopen(fort_events_file, \"a\"))!=NULL) {\n      fprintf(fp1,\"id=%d\", event_id);\n      fprintf(fp1,\", source=%02d\", source);\n      fprintf(fp1,\", pool=%02d\", *pool);\n      fprintf(fp1,\", mode=%d\", mode);\n      fprintf(fp1,\", len=%d\", len);\n      fprintf(fp1,\", data=\");\n      for(int c=0;c&lt;len;c++)\n        fprintf(fp1,\"%02x\", buf&#91;c]);\n      fprintf(fp1,\"\\n\");\n      fflush(fp1);\n      fclose(fp1);\n      event_id++;\n    }\n  }\n#endif\n\n  switch(mode) {\n\n  case 1:\n    (*pool) = ((*pool)+1) % FORT_POOLS;\n    break;\n\n  case 3:\n    break; \/\/ caller decides next pool\n\n  }\n}\n\nvoid fort_add_random_event_timer_start(IUTIME *micros)\n{\n  *micros = getmicroseconds();\n}\n\nvoid fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *micros)\n{\n  unsigned char temp&#91;2];\n  IUTIME t;\n\n  t = getmicroseconds()-*micros;\n  temp&#91;0] = t &amp; 0xff;\n  temp&#91;1] = (t&gt;&gt;8) &amp; 0xff;\n\n  fort_add_random_event(pool, source, mode,\n\t\t\tsizeof(temp), temp);\n}\n\nvoid fort_add_random_event_time(int *pool, int source, int mode)\n{\n  int len;\n  unsigned char temp&#91;2];\n  IUTIME t;\n  static int prev_second=-1;\n\n  t = getmicroseconds();\n  temp&#91;0] = t &amp; 0xff;\n  temp&#91;1] = (t&gt;&gt;8) &amp; 0xff;\n  len=2;\n\n  if(prev_second==temp&#91;1]) {\n    len--;\n  } else {\n    prev_second=temp&#91;1];\n  }\n\n  fort_add_random_event(pool, source, mode,\n\t       len, temp);\n}\n\nvoid fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf, int size)\n{\n  int n;\n\n  while(len != 0) {\n    n = (size&lt;len)? size:len;\n    fort_add_random_event(pool, source,\n        mode, n, buf);\n    buf += n;\n    len -= n;\n  }\n}\n\n#define aDEBUG18 2\n\nvoid hash_init(HashCtx *hash)\n{\n  FORT_INTERNAL_EVENTS_START(10)\n\n  HashInit(hash);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"init\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(11)\n}\n\nvoid hash_update(HashCtx *hash, unsigned char *data, int len)\n{\n  FORT_INTERNAL_EVENTS_START(12)\n\n  HashUpdate(hash, data, len);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"data   \");\n  for(int d=0;d&lt;len;d++)\n    fprintf(stdout,\"%02x\",data&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(13)\n}\n\nvoid hash_final(unsigned char digest&#91;HashLen], HashCtx *hash)\n{\n  FORT_INTERNAL_EVENTS_START(14)\n\n  HashFinal(digest, hash);\n\n#ifdef DEBUG18\n  fprintf(stdout,\"digest \");\n  for(int d=0;d&lt;HashLen;d++)\n    fprintf(stdout,\"%02x\",digest&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  FORT_INTERNAL_EVENTS_END(15)\n}\n\nstatic unsigned char fort_key&#91;HashLen];\n\nvoid fort_rekey(unsigned char *digest)\n{\n  HashCtx hash;\n\n  FORT_INTERNAL_EVENTS_START(16)\n\n  hash_init(&amp;hash);\n  hash_update(&amp;hash, fort_key, sizeof(fort_key));\n  hash_update_cvar(&amp;hash);\n  hash_final(digest, &amp;hash);\n\n  \/\/ Forget hash\n\n  memset(&amp;hash, 0, sizeof(hash));\n\n  FORT_INTERNAL_EVENTS_END(17)\n}\n\n#define FORT_PSEUDO_LIMIT 1048576\n\n\/\/ use \n\/\/ $ .\/newressu --fort -x -w32 -s2 -l2000 --space | more\n\/\/ to debug...\n\n\/\/ choose one of\n\/\/     60 (1 minute)\n\/\/     300 (5 minutes)\n\/\/     600 (10 minutes)\n\/\/     900 (15 minutes)\n\/\/     1200 (20 minutes)\n\/\/     1800 (30 minutes)\n\/\/     3600 (hour)\n\/\/     7200 (2 hours)\n\/\/     10800 (3 hours)\n\/\/     14400 (4 hours)\n\/\/     21600 (6 hours)\n\/\/     28800 (8 hours)\n\/\/     43200 (12 hours)\n\/\/     86400 (24 hours)\n\/\/ to get readable report..\n\n#define FORT_SECONDS_BETWEEN_SAVES 10*60\nstatic IUTIME fort_next_save = 0;\n\n#define TIMEFORMAT \"%Z%Y%m%d%H%M%S\"\n\nvoid fort_save();\n\nstatic char current_timezone&#91;10];\n\n#define aDEBUG22 2\n\nvoid fort_reseed(int len, unsigned char *buf)\n{\n  HashCtx hash;\n\n  FORT_INTERNAL_EVENTS_START(22)\n\n    \n  hash_init(&amp;hash);\n  hash_update(&amp;hash, fort_key, sizeof(fort_key));\n  hash_update_cvar(&amp;hash);\n  hash_update(&amp;hash, buf, len);\n\n#ifdef DEBUG22\n  fprintf(stdout,\"\\nprevkey   \");\n  for(int d=0;d&lt;sizeof(fort_key);d++)\n    fprintf(stdout,\"%02x\",fort_key&#91;d]);\n  fprintf(stdout,\"\\ncvar      \");\n  for(int d=0;d&lt;cvarsize+1;d++)\n    fprintf(stdout,\"%02x\",cvar&#91;d]);\n  fprintf(stdout,\"\\ndata      \");\n  for(int d=0;d&lt;HashLen;d++)\n    fprintf(stdout,\"%02x\",buf&#91;d]);\n  fprintf(stdout,\"\\ndata asc  \");\n  for(int d=0;d&lt;len;d++) {\n    if(isprint(buf&#91;d]))\n      fprintf(stdout,\"%c\",buf&#91;d]);\n    else\n      fprintf(stdout,\"\\\\%02x\",buf&#91;d]);\n  }\n#endif\n  \n  hash_final(fort_key, &amp;hash);\n\n#ifdef DEBUG22\n  fprintf(stdout,\"\\nnewkey    \");\n  for(int d=0;d&lt;sizeof(fort_key);d++)\n    fprintf(stdout,\"%02x\",fort_key&#91;d]);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  memset(&amp;hash, 0, sizeof(hash));\n\n  if(fort_next_save != 0) {\n    IUTIME seconds;\n    seconds = getseconds();\n    \n    char timezone&#91;10];\n    strftime(timezone, sizeof(timezone), \"%Z\",\n             localtime((time_t *)&amp;seconds) );\n    if(strcmp(current_timezone,timezone)) {\n      fort_next_save=1;\n      strcpy(current_timezone,timezone);\n    }\n    \n    if(fort_next_save != 0 &amp;&amp;\n       seconds &gt;= fort_next_save) {\n      \n      IUTIME diff=\n        timegm(localtime((time_t *)&amp;seconds))-seconds;\n      \n      fort_next_save = seconds -\n        ((seconds+diff) %\n         FORT_SECONDS_BETWEEN_SAVES) +\n        FORT_SECONDS_BETWEEN_SAVES;\n      \n      fort_save();\n    }\n  }\n\n  FORT_INTERNAL_EVENTS_END(23)\n}\n\nstatic FORT_COUNTER fort_reseed_count = 0;\nstatic IUTIME fort_next_reseed = 0;\n\n#define aDEBUG28 2\n\n#ifdef FORT_ORIGINAL_VERSION\n\nvoid fort_pseudo_random_data(int len, \n    unsigned char *buf)\n{\n  unsigned char digest&#91;HashLen];\n  unsigned int n, blockbytes;\n#ifdef DEBUG28\n  int d=0;\n#endif\n\n  FORT_INTERNAL_EVENTS_START(18)\n\n  blockbytes = 0;\n\n  while(len != 0) {\n    FORT_INTERNAL_EVENTS_START(19)\n\n    fort_rekey(digest);\n    n = (len&lt;HashLen) ? len : HashLen;\n\n#ifdef DEBUG28\n    \n    fprintf(stdout,\"\\nbuf(%02x):  \",d++);\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]);\n    fprintf(stdout,\"\\ndigest:   \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",digest&#91;c]);\n    fprintf(stdout,\"\\nsum:      \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]^digest&#91;c]);\n    fprintf(stdout,\"\\n\");\n\n#endif \/\/ #ifdef DEBUG18\n\n    memcpy(buf, digest, n);\n\n    buf += n;\n    len -= n;\n    blockbytes += n;\n\n    \/\/ rekey every 1048576 bytes if data left\n\n    if(blockbytes &gt;= FORT_PSEUDO_LIMIT &amp;&amp;\n        len &gt; 0) {                                                                                                              \n      fort_rekey(fort_key);\n      blockbytes = 0;\n    }\n\n    FORT_INTERNAL_EVENTS_END(20)\n  }\n\n  fort_rekey(fort_key);\n\n  \/\/ Forget last bytes\n\n  memset(digest, 0, sizeof(digest));\n\n  FORT_INTERNAL_EVENTS_END(21)\n}\n\n#define aDEBUG34 2\n\nvoid fort_random_data(int len, unsigned char *buf)\n{\n  int c;\n  IUTIME tenths;\n  HashCtx hash;\n  unsigned char digest&#91;HashLen];\n\n  FORT_INTERNAL_EVENTS_START(24)\n\n  tenths=gettenths();\n\n  if( (fort_next_reseed == 0) ||\n      (fort_next_reseed &lt;= tenths &amp;&amp;\n      fort_pools&#91;0].length &gt;=\n      FORT_MIN_POOL_SIZE) ) {\n\n    fort_mix();\n    \n    \/\/ next tenth of a second\n\n    fort_next_reseed = tenths + 1;\n    fort_reseed_count++;\n\n    hash_init(&amp;hash);\n    c=0;\n\n    while(c &lt; FORT_POOLS &amp;&amp; (fort_reseed_count\n        % (1&lt;&lt;c)) == 0) {\n\n      FORT_INTERNAL_EVENTS_START(25)\n\n      hash_final(digest, &amp;fort_pools&#91;c].pool);\n\n#ifdef DEBUG34\n      fprintf(stdout,\"\\ndata   %2d \",c);\n      for(int d=0;d&lt;HashLen;d++)\n\tfprintf(stdout,\"%02x\",digest&#91;d]);\n#endif\n\n      hash_update(&amp;hash, digest, sizeof(digest));\n      fort_pools&#91;c].length = 0;\n      HashInit(&amp;fort_pools&#91;c].pool);\n\n      \/\/ save earlier pool to new one\n\n      hash_update(&amp;fort_pools&#91;c].pool,\n        digest, sizeof(digest));\n      c++;\n\n      FORT_INTERNAL_EVENTS_END(26)\n    }\n    hash_update_cvar(&amp;hash);\n    hash_final(digest, &amp;hash);\n\n#ifdef DEBUG34\n    fprintf(stdout,\"\\ndigest    \");\n    for(int d=0;d&lt;HashLen;d++)\n      fprintf(stdout,\"%02x\",digest&#91;d]);\n    fprintf(stdout,\"\\n\");\n#endif\n\n    fort_reseed(sizeof(digest), digest);\n\n    \/\/ Forget hash context\n\n    memset(&amp;hash, 0, sizeof(hash));\n\n    \/\/ Forget reseed key\n\n    memset(digest, 0, sizeof(digest));\n  }\n\n  fort_pseudo_random_data(len, buf);\n\n  FORT_INTERNAL_EVENTS_END(27)\n}\n\n#endif \/\/ #ifdef FORT_ORIGINAL_VERSION\n\n#ifdef FORT_XOR_VERSION\n\nvoid fort_pseudo_random_data_xor(int len, \n    unsigned char *buf)\n{\n  unsigned char digest&#91;HashLen];\n  unsigned int n, blockbytes;\n#ifdef DEBUG28\n  int d=0;\n#endif\n\n  FORT_INTERNAL_EVENTS_START(18)\n\n  blockbytes = 0;\n\n  while(len != 0) {\n    FORT_INTERNAL_EVENTS_START(19)\n      \n    fort_rekey(digest);\n    n = (len&lt;HashLen) ? len : HashLen;\n\n#ifdef DEBUG28\n\n    fprintf(stdout,\"\\nbuf(%02x):  \",d++);\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]);\n    fprintf(stdout,\"\\ndigest:   \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",digest&#91;c]);\n    fprintf(stdout,\"\\nsum:      \");\n    for(int c=0;c&lt;n;c++)\n      fprintf(stdout,\"%02x\",buf&#91;c]^digest&#91;c]);\n    fprintf(stdout,\"\\n\");\n\n#endif\n    \n    for(int c=0;c&lt;n;c++)\n      buf&#91;c]^=digest&#91;c];\n\n    buf += n;\n    len -= n;\n    blockbytes += n;\n\n    \/\/ rekey every 1048576 bytes if data left\n\n    if(blockbytes &gt;= FORT_PSEUDO_LIMIT &amp;&amp;\n        len &gt; 0) {                                                                                                              \n      fort_rekey(fort_key);\n      blockbytes = 0;\n    }\n\n    FORT_INTERNAL_EVENTS_END(20)\n  }\n\n  fort_rekey(fort_key);\n\n  \/\/ Forget last bytes\n\n  memset(digest, 0, sizeof(digest));\n\n  FORT_INTERNAL_EVENTS_END(21)\n}\n\nvoid fort_random_data_xor(int len, unsigned char *buf)\n{\n  int c;\n  IUTIME tenths;\n  HashCtx hash;\n  unsigned char digest&#91;HashLen];\n\n  FORT_INTERNAL_EVENTS_START(24)\n\n  tenths=gettenths();\n\n  if( (fort_next_reseed == 0) ||\n      (fort_next_reseed &lt;= tenths &amp;&amp;\n      fort_pools&#91;0].length &gt;=\n      FORT_MIN_POOL_SIZE) ) {\n\n    fort_mix();\n\n    \/\/ next tenth of a second\n\n    fort_next_reseed = tenths + 1;\n    fort_reseed_count++;\n\n    hash_init(&amp;hash);\n    c=0;\n\n    while(c &lt; FORT_POOLS &amp;&amp; (fort_reseed_count\n        % (1&lt;&lt;c)) == 0) {\n\n      FORT_INTERNAL_EVENTS_START(25)\n\n      hash_final(digest, &amp;fort_pools&#91;c].pool);\n\n#ifdef DEBUG34\n      fprintf(stdout,\"\\ndata   %2d \",c);\n      for(int d=0;d&lt;HashLen;d++)\n\tfprintf(stdout,\"%02x\",digest&#91;d]);\n#endif\n      \n      hash_update(&amp;hash, digest, sizeof(digest));\n      fort_pools&#91;c].length = 0;\n      HashInit(&amp;fort_pools&#91;c].pool);\n\n      \/\/ save earlier pool to new one\n\n      hash_update(&amp;fort_pools&#91;c].pool,\n        digest, sizeof(digest));\n      c++;\n\n      FORT_INTERNAL_EVENTS_END(26)\n    }\n    hash_update_cvar(&amp;hash);\n    hash_final(digest, &amp;hash);\n\n#ifdef DEBUG34\n    fprintf(stdout,\"\\ndigest    \");\n    for(int d=0;d&lt;HashLen;d++)\n      fprintf(stdout,\"%02x\",digest&#91;d]);\n    fprintf(stdout,\"\\n\");\n#endif\n    \n    fort_reseed(sizeof(digest), digest);\n\n    \/\/ Forget hash context\n\n    memset(&amp;hash, 0, sizeof(hash));\n\n    \/\/ Forget reseed key\n\n    memset(digest, 0, sizeof(digest));\n  }\n\n  fort_pseudo_random_data_xor(len, buf);\n\n  FORT_INTERNAL_EVENTS_END(27)\n}\n\n#endif \/\/ #ifdef FORT_XOR_VERSION\n\n#define FORTCNT 128\n\nstatic unsigned int fort_cnt = FORTCNT;\nstatic unsigned char fort_bytes&#91;FORTCNT];\nstatic int fort_byte = 999999999;\n\nint fort_random_data_byte()\n{\n  if(fort_byte &gt;= fort_cnt) {\n    fort_random_data(fort_cnt, fort_bytes);\n    fort_byte = 0;\n  }\n  return(fort_bytes&#91;fort_byte++]);\n}\n\nvoid fort_clear()\n{\n  memset(fort_bytes, 0, fort_cnt);\n  fort_byte = 999999998;\n}\n\nint fort_random_data_byte_limit(int limit)\n{\n  int c;\n\n  while((c = fort_random_data_byte())&gt;=\n      (256\/limit)*limit);\n\n  return(c % limit);\n}\n\nvoid fort_random_data_buffer(int size,\n    unsigned char *buffer)\n{\n  int c;\n\n  for(c=0; c&lt;size; c++)\n    buffer&#91;c] ^= fort_random_data_byte();\n}\n\n#define aDEBUG53 2\n\nvoid fort_reseed_file(unsigned char *filename)\n{\n  int c, cnt, bytes, characters;\n#ifdef DEBUG53\n  unsigned char *p;\n#endif\n  FILE *fp1;\n  unsigned char buffer&#91;1024], digest&#91;HashLen];\n\n  HashCtx hash;\n\n  bytes=0;\n  characters=0;\n  \n  if((fp1=fopen(filename, \"r\"))!=NULL) {\n    HashInit(&amp;hash);\n    while(fgets(buffer,sizeof(buffer),fp1)!=NULL) {\n      cnt=strlen(buffer);\n      HashUpdate(&amp;hash, buffer, cnt);\n      bytes+=cnt;\n      for(c=0;c&lt;cnt;c++) {\n\tif(buffer&#91;c]&lt;0x80 || buffer&#91;c]&gt;0xbf)\n\t  characters++;\n      }\n#ifdef DEBUG53\n      p=buffer;\n      while(*p!='\\0') {\n\tif(*p=='\\\\')\n\t  fprintf(stdout,\"\\\\\\\\\");\n\telse if(isprint(*p) || *p=='\\n')\n\t  fputc(*p,stdout);\n\telse\n\t  fprintf(stdout,\"\\\\%02x\",*p);\n\tp++;\n      }\n#endif\n    }\n    hash_update_cvar(&amp;hash);\n    HashFinal(digest, &amp;hash);\n\n    fort_reseed(sizeof(digest), digest);\n\n    fclose(fp1);\n  }\n#ifdef DEBUG53\n  \/\/if(fort_verbose) {\n  fprintf(stdout,\"fort_reseed_file %s\",filename);\n  fprintf(stdout,\", %d bytes read\",bytes);\n  fprintf(stdout,\", %d characters read\",characters);\n  fprintf(stdout,\", sha256: \");\n  for(int c = 0;c &lt; HashLen; c++) {\n    fprintf(stdout,\"%02x\", digest&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  \/\/}\n#endif\n}\n\n#define FORT_SAVE_SIZE 1024\n\n#define aDEBUG57\n\nvoid fort_save()\n{\n  FILE *fp1;\n  unsigned char buffer&#91;FORT_SAVE_SIZE];\n\n  memset(buffer,0,sizeof(buffer));\n\n  if((fp1 = fopen(fort_random_file, \"w\")) != NULL) {\n    fort_pseudo_random_data(sizeof(buffer), buffer);\n\n#ifdef DEBUG57\n    for(int c=0;c&lt;sizeof(buffer);c++) {\n      if(c%32==0) {\n\tif(c!=0)\n\t  fprintf(stdout,\"\\n\");\n\tfprintf(stdout,\"save      %05d \",c);\n      }\n      fprintf(stdout,\" %02x\",buffer&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n#endif\n    fwrite(buffer, 1, sizeof(buffer), fp1);\n    memset(buffer, 0, sizeof(buffer));\n    fclose(fp1);\n  }\n}\n\nvoid fort_restore()\n{\n  int d;\n#ifdef DEBUG57\n  int random;\n#endif\n  FILE *fp1;\n  unsigned char buffer&#91;FORT_SAVE_SIZE];\n\n  memset(buffer,0,sizeof(buffer));\n  \n  if((fp1 = fopen(fort_random_file, \"r\"))\n      != NULL) {\n    d = fread(buffer, 1, sizeof(buffer), fp1);\n    fclose(fp1);\n#ifdef DEBUG57\n    random=0;\n#endif\n  } else {\n    fort_pseudo_random_data(sizeof(buffer), buffer);\n    ressu_genbytes(sizeof(buffer), buffer);\n    d = sizeof(buffer);\n#ifdef DEBUG57\n    random=1;\n#endif\n  }\n#ifdef DEBUG57\n  for(int c=0;c&lt;sizeof(buffer);c++) {\n    if(c%32==0) {\n      if(c!=0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"restore\");\n      if(random)\n\tfprintf(stdout,\"*\");\n      else\n\tfprintf(stdout,\" \");\n      fprintf(stdout,\"  %05d \",c);\n    }\n    fprintf(stdout,\" %02x\",buffer&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n#endif\n  fort_reseed(d, buffer);\n  memset(buffer, 0, sizeof(buffer));\n\n  fort_save();\n}\n\n#if defined FORT_USE_URANDOM || \\\n    defined FORT_USE_RANDOM\n\nstatic void fort_readfile_xor(int len,\n    unsigned char *buf,\n    unsigned char *filename)\n{\n  int c, n, n2;\n  unsigned char temp&#91;64];\n  FILE *fp1;\n\n  if((fp1 = fopen(filename, \"rb\"))\n      != NULL) {\n    while(len != 0) {\n      n = (len &lt; sizeof(temp)) ?\n          len : sizeof(temp);\n      n2=fread(temp, 1, n, fp1);\n      for(c = 0; c &lt; n2; c++)\n        buf&#91;c] ^= temp&#91;c];\n      len -= n2;\n      buf += n2;\n    }\n    fclose(fp1);\n  }\n}\n\n#endif\n\n#ifdef FORT_USE_WEB\n\nstatic void parse_string(unsigned char *string, int size, unsigned char **p2)\n{\n  int count;\n  unsigned char *p, *q;\n\n  p=*p2;\n  q=string;\n  count=0;\n\n  \/\/ uppercase &amp; lowercase letters, '.'\n  \/\/ or utf-8\n\n  while(isalnum(*p)||*p=='.'||*p&gt;0x80) {\n    if(++count&lt;size)\n      *q++=*p;\n    p++;\n  }\n  *q='\\0';\n  *p2=p;\n}\n\n#endif \/\/ #ifdef FORT_USE_WEB\n\n#ifdef FORT_USE_WEB\n\nstatic int check_string(unsigned char *string, unsigned char *p)\n{\n  int ok;\n\n  ok=0;\n  if(!strncmp(string,p,strlen(string))) {\n    ok=1;\n  }\n\n  return(ok);\n}\n\n#endif \/\/ #ifdef FORT_USE_WEB\n\nvoid fort_internal_random_data_1(int size, char *buf)\n{\n  ressu_genbytes(size, buf);\n#ifdef FORT_XOR_VERSION\n  fort_pseudo_random_data_xor(size, buf);\n#endif\n}\n\nvoid fort_internal_random_data_2(int size, char *buf)\n{\n#ifdef FORT_XOR_VERSION\n  fort_pseudo_random_data_xor(size, buf);\n#else\n  fort_pseudo_random_data(size, buf);\n#endif\n  ressu_genbytes(size, buf);\n}\n\nvoid fort_internal_random_data_3(int size, char *buf)\n{\n#ifdef FORT_XOR_VERSION\n  fort_random_data_xor(size, buf);\n#else\n  fort_random_data(size, buf);\n#endif\n}\n\nstatic IUTIME fort_next_localmix = 0;\n\/\/#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60\n#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60\nstatic IUTIME fort_next_webmix = 0;\n\/\/#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600\n#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600\n\n#define RANDOMNESS_IN_LANGUAGES 2\n\nvoid fort_mix()\n{\n  int webmix=0, localmix=0;\n  unsigned char temp&#91;64];\n\n  IUTIME seconds;\n\n  seconds = getseconds();\n  \n  webmix=0;\n  localmix=0;\n\n  if(fort_next_webmix == 0 ||\n     fort_next_webmix &lt;= seconds) {\n    fort_next_webmix=seconds+FORT_SECONDS_BETWEEN_WEBMIXES;\n    fort_next_localmix=seconds+FORT_SECONDS_BETWEEN_LOCALMIXES;\n    webmix=1;\n    localmix=1;\n  }\n\n  if(fort_next_localmix == 0 ||\n     fort_next_localmix &lt;= seconds) {\n    fort_next_localmix=seconds+FORT_SECONDS_BETWEEN_LOCALMIXES;\n    localmix=1;\n  }\n\n  if(!webmix &amp;&amp; !localmix)\n    return;\n  \n  if(fort_verbose) {  \n    char timebuf&#91;128];\n    strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t     localtime((time_t *)&amp;seconds));\n    fprintf(stdout,\"Fort mix time:      %s\\n\",timebuf);\n    strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t     localtime((time_t *)&amp;fort_next_webmix));\n    fprintf(stdout,\"Next fort webmix:   %s\\n\",timebuf);\n    strftime(timebuf, sizeof(timebuf), TIMEFORMAT,\n\t     localtime((time_t *)&amp;fort_next_localmix));\n    fprintf(stdout,\"Next fort localmix: %s\\n\",timebuf);\n  }\n  \n  fort_internal_random_data_1(sizeof(temp), temp);\n  fort_reseed(sizeof(temp), temp);\n  \n#if defined FORT_USE_WEB || \\\n  defined FORT_USE_RDRAND || \\\n  defined FORT_USE_RDSEED || \\\n  defined FORT_USE_NEWRESSU_COMMAND\n  unsigned char digest&#91;HashLen];\n#endif    \n  \n#ifdef FORT_USE_WEB\n  if(webmix &amp;&amp; fort_use_web) {\n    char *webpages&#91;] = {\n      \"https:\/\/moijari.com:5001\/\",\n      \"https:\/\/moijari.com:5005\/\",\n      \"https:\/\/moijari.com:5006\/\",\n    };\n\n    for(int c=0;c&lt;sizeof(webpages)\/sizeof(webpages&#91;0]);c++) {\n      unsigned char *p;\n      \n      unsigned char scheme&#91;32];\n      unsigned char host&#91;32];\n      unsigned char port&#91;10];\n      unsigned char rest&#91;128];\n      \n      p=webpages&#91;c];\n      parse_string(scheme,sizeof(scheme),&amp;p);\n      \n      if(check_string(\":\/\/\",p)) {\n\tp+=3;\n\tparse_string(host,sizeof(host),&amp;p);\n      } else {\n\tstrcpy(host,scheme);\n\tstrcpy(scheme,\"http\");\n      }\n      \n      if(check_string(\":\",p)) {\n\tp++;\n\tparse_string(port,sizeof(port),&amp;p);\n      } else {\n\tstrcpy(port,\"80\");\n      }\n      \n      if(*p!='\/') \n\tstrcpy(rest,\"\/\");\n      else\n\tstrcpy(rest,p);\n      \n      if(fort_verbose) {    \n\tfprintf(stdout,\"URL:%s \",webpages&#91;c]);\n\tfprintf(stdout,\"&#91;scheme:%s]\",scheme);\n\tfprintf(stdout,\"&#91;host:%s]\",host);\n\tfprintf(stdout,\"&#91;port:%s]\",port);\n\tfprintf(stdout,\"&#91;rest:%s]\",p);\n\tfflush(stdout);\n      }\n      \n      if(!strcmp(scheme,\"http\")) {\n\tfort_hash_http_page(host, port, p, digest);\n      } else if(!strcmp(scheme,\"https\")) {\n\tfort_hash_https_page(host, port, p, digest);\n      }\n      if(fort_verbose) {\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n      }\n      fort_reseed(sizeof(digest), digest);\n    }\n  }\n#endif \/\/ #ifdef FORT_USE_WEB\n    \n  if(localmix) {    \n#ifdef FORT_USE_URANDOM\n    memset(temp, 0, sizeof(temp));\n    fort_readfile_xor(sizeof(temp), temp,\n\t\t      \"\/dev\/urandom\");\n    fort_reseed(sizeof(temp), temp);\n#endif\n  \n#ifdef FORT_USE_RANDOM\n    memset(temp, 0, sizeof(temp));\n    fort_readfile_xor(sizeof(temp), temp,\n\t\t      \"\/dev\/random\");\n    fort_reseed(sizeof(temp), temp);\n#endif\n\n#if defined FORT_USE_RDRAND || \\\n  defined FORT_USE_RDSEED\n    HashCtx hash;\n    unsigned char digest&#91;HashLen];\n#endif\n    \n#ifdef FORT_USE_RDRAND\n\n    memset(temp,0,sizeof(temp));\n    if(rdrand_bytes(sizeof(temp),temp)) {\n      \n      HashInit(&amp;hash);\n      \n      hash_update_cvar(&amp;hash);\n\n      HashUpdate(&amp;hash, temp, sizeof(temp));\n      HashFinal(digest, &amp;hash);\n      \n      if(fort_verbose) {\n\tfprintf(stdout,\", sha256: \");\n\tfor(int c = 0;c &lt; HashLen; c++) {\n\t  fprintf(stdout,\"%02x\", digest&#91;c]);\n\t}\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n      }\n      \n      fort_reseed(sizeof(digest), digest);\n    }  \n    \n#endif \/\/ #ifdef FORT_USE_RDRAND\n  \n#ifdef FORT_USE_RDSEED\n  \n    memset(temp,0,sizeof(temp));\n    if(rdseed_bytes(sizeof(temp),temp)) {\n      \n      HashInit(&amp;hash);\n\n      hash_update_cvar(&amp;hash);\n\n      HashUpdate(&amp;hash, temp, sizeof(temp));\n      HashFinal(digest, &amp;hash);\n      \n      if(fort_verbose) {\n\tfprintf(stdout,\", sha256: \");\n\tfor(int c = 0;c &lt; HashLen; c++) {\n\t  fprintf(stdout,\"%02x\", digest&#91;c]);\n\t}\n\tfprintf(stdout,\"\\n\");\n\tfflush(stdout);\n      }\n      \n      fort_reseed(sizeof(digest), digest);\n    }\n\n#endif \/\/ #ifdef FORT_USE_RDSEED\n\n#ifdef FORT_USE_NEWRESSU_COMMAND\n\n    char *commands&#91;] = {\n      \"\/bin\/newressu -2 -s8 -c64 -l1 --lineno\",\n      \"\/bin\/newressu -2 -s8 -c64 -l1 --lineno --fast\",\n      \"\/bin\/newressu -2 -s8 -c64 -l1 --lineno --urandom\",\n#ifdef RANDOMNESS_IN_LANGUAGES\n      \"\/bin\/newressu --cn -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --deu -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --dnk -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --eng -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --est -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --fin -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --fra -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --gbr -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --got -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --grc -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --ita -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --jp -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --jp1 -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --jp2 -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --jp3 -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --kor -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --ltu -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --lva -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --nor -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --rus -s8 -c64 -l1 --single --lineno\",\n      \"\/bin\/newressu --swe -s8 -c64 -l1 --single --lineno\",\n#endif\n    };\n\n    for(int c=0;c&lt;sizeof(commands)\/sizeof(commands&#91;0]);c++) {\n      if(strstr(commands&#91;c], \"--fort\")) {\n\tfprintf(stderr,\"%s: fort_mix(): cannot call fort recursively \\\"%s\\\"\\n\",\n\t\tprocname,commands&#91;c]);\n      } else {\n\tfort_hash_command(commands&#91;c], digest);\n\tfort_reseed(sizeof(digest), digest);\n      }\n    }\n#endif \/\/ #ifdef FORT_USE_NEWRESSU_COMMAND\n  }\n}\n\nvoid file_digest(char *filename,unsigned char temp&#91;HashLen])\n{\n  int c;\n  unsigned char buffer&#91;1024];\n  FILE *fp1;\n  HashCtx ctx;\n  \n  HashInit(&amp;ctx);\n  if((fp1=fopen(filename,\"rb\"))!=NULL) {\n    while((c=fread(buffer,1,sizeof(buffer),fp1))&gt;0)\n      HashUpdate(&amp;ctx,buffer,c);\n    fclose(fp1);\n  }\n  HashFinal(temp,&amp;ctx);\n}\n\n#define DEBUG88\n\nvoid fort_init()\n{\n  int c;\n  unsigned char temp32&#91;32];\n\n  memset(temp32,0,sizeof(temp32));\n  memset(fort_bytes,0,sizeof(fort_bytes));\n  memset(fort_key,0,sizeof(fort_key));\n  \n  if(fort_verbose) {\n    fprintf(stdout,\"hash: %s\",\n\t    HashName);\n    fprintf(stdout,\", pools: %d*%ld\", FORT_POOLS,\n\t    sizeof(struct fort_pool));\n    fprintf(stdout,\", HashCtx: %ld\",\n\t    sizeof(HashCtx));\n    fprintf(stdout,\", hashsize: %d\",\n\t    HashLen);\n    fprintf(stdout,\"\\n\");\n  }\n  \n  unsigned int save_fort_internal_events;\n  save_fort_internal_events=fort_internal_events;\n  fort_internal_events=1;\n\n  fort_next_save = 0;\n  \n  clearcvar();\n\n  \/\/ first key to fort_key\n  \n  fort_internal_random_data_1(sizeof(fort_key), fort_key);\n\n#ifdef ADDITIONAL_SECRETS  \n\n  \/\/ additional constant randomness from program\n\n  fort_reseed(strlen(copyright), copyright);\n  fort_reseed(strlen(programname), programname);\n\n  unsigned char filedigest&#91;HashLen];\n  file_digest(\"\/proc\/self\/exe\",filedigest);\n  fort_reseed(strlen(filedigest), filedigest);\n  \n  fort_reseed(strlen(programsecret), programsecret);\n\n  \/\/ additional constant randomness\n  \/\/ from you (one more secret adversary\n  \/\/ has to guess)\n\n  FILE *fp1;\n  if((fp1 = fopen(fort_secret_file, \"r\")) != NULL) {\n    fclose(fp1);\n  } else {\n    if((fp1 = fopen(fort_secret_file, \"w\")) != NULL) {\n      fprintf(fp1,\"Your secret additional constant data to fort:\\n\");\n      fclose(fp1);\n      unsigned char temp2&#91;160];\n      sprintf(temp2,\"%s -2 -l1 &gt;&gt;%s\",procname,fort_secret_file);\n      system(temp2);\n      fprintf(stdout,\"File %s written\\n\",fort_secret_file);\n    }\n  }\n  fort_reseed_file(fort_secret_file);\n\n#endif\n  \n  \/\/ Initialize buffers\n\n  for(c=0; c&lt;FORT_POOLS; c++) {\n    fort_pools&#91;c].length = 0;\n    HashInit(&amp;fort_pools&#91;c].pool);\n  }\n\n#ifdef DEBUG10\n\n  FILE *fp1;\n  \n  \/\/ Empty events file\n\n  if((fp1 = fopen(fort_events_file, \"w\"))!=NULL)\n    fclose(fp1);\n  event_id = 0;\n\n#endif \/\/ #ifdef DEBUG10\n\n  \/\/ Mix fort key with web + local\n  \/\/ random numbers\n  \n  fort_mix();\n\n  for(c=0; c&lt;FORT_POOLS; c++) {\n    FORT_INTERNAL_EVENTS_START(31)\n    fort_internal_random_data_2(sizeof(temp32), temp32);\n    hash_update(&amp;fort_pools&#91;c].pool,\n      temp32, sizeof(temp32));\n    FORT_INTERNAL_EVENTS_END(32)\n  }\n\n#ifdef FORT_INTERNAL_EVENTS\n\n  if(fort_internal_events) {\n\n    \/\/ Create some internal events\n\n    for(c=0; c&lt;32; c++) {\n      FORT_INTERNAL_EVENTS_START(34)\n      fort_internal_random_data_3(sizeof(temp32), temp32);\n      FORT_INTERNAL_EVENTS_END(35)\n    }\n  }\n\n#endif \/\/ #ifdef FORT_INTERNAL_EVENTS\n\n  fort_reseed_count = 0;\n  fort_next_reseed = 0;\n\n  \/\/ Reseed fort_key with new events\n\n  fort_internal_random_data_3(sizeof(temp32), temp32);\n  fort_reseed(sizeof(temp32), temp32);\n\n  fort_restore();\n\n  \/\/ Forget temp\n\n  memset(temp32,0,sizeof(temp32));\n\n  fort_internal_events = save_fort_internal_events;\n\n  \/\/fort_reseed_count = 0;\n  \/\/fort_next_reseed = 0;\n\n  fort_next_save = 1;\n}\n\nvoid fort_version()\n{\n  fprintf(stderr,\"%s\",programname); \/\/ touch these outside MAIN\n  fprintf(stderr,\", %s\\n\",copyright);\n}\n\n#define aMAIN 2\n#ifdef MAIN\n\nunsigned char *procname;\n\nint main(int argc, char *argv&#91;])\n{\n  procname=argv&#91;0];\n  fort_version();\n  fort_init();\n  return(0);\n}\n\n#endif \/\/ #ifdef MAIN<\/code><\/pre>\n\n\n\n<p>sha256.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Written from SHA256 documents by Jari Kuivaniemi, read \"http:\/\/en.wikipedia.org\/wiki\/SHA-2\" *\/\n#include &lt;stdio.h&gt;\n#include &lt;memory.h&gt;\n#include &lt;string.h&gt;\n\n#include \"sha256.h\"\n\nextern unsigned char *procname;\n\n\/\/#ifdef MAIN \/\/ in Makefile\n\nunsigned char *sha_name=\"SHA256 v1.0\";\n\nvoid SHA256Init(SHA256_CONTEXT *sha256)\n{\n  sha256-&gt;state&#91;0] = 0x6a09e667;\n  sha256-&gt;state&#91;1] = 0xbb67ae85;\n  sha256-&gt;state&#91;2] = 0x3c6ef372;\n  sha256-&gt;state&#91;3] = 0xa54ff53a;\n  sha256-&gt;state&#91;4] = 0x510e527f;\n  sha256-&gt;state&#91;5] = 0x9b05688c;\n  sha256-&gt;state&#91;6] = 0x1f83d9ab;\n  sha256-&gt;state&#91;7] = 0x5be0cd19;\n  \n  sha256-&gt;count = 0;\n}\n\nIUWORD k256&#91;64] = {\n  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n};\n\n#define RR32(word,bits) ( ((word) &gt;&gt; (bits)) | ((word) &lt;&lt; (32 - (bits))) )\n#define RS32(word,bits) ( ((word) &gt;&gt; (bits)) )\n\nvoid SHA256Transform(IUWORD state&#91;8], IUBYTE buffer&#91;64])\n{\n  int i;\n  \n  IUWORD w&#91;64], s0;\n  IUWORD a, b, c, d, e, f, g, h;\n  IUWORD maj, t2, s1;\n  IUWORD ch, t1;\n  \n  for(i=0;i&lt;16;i++) {\n    w&#91;i] =\n      (IUWORD)buffer&#91;i*4+0] &lt;&lt; 24 |\n      (IUWORD)buffer&#91;i*4+1] &lt;&lt; 16 |\n      (IUWORD)buffer&#91;i*4+2] &lt;&lt; 8  |\n      (IUWORD)buffer&#91;i*4+3];\n  }\n  \n  for(i=16;i&lt;64;i++) {\n    s0 = (RR32(w&#91;i-15],7)) ^ (RR32(w&#91;i-15],18)) ^ (RS32(w&#91;i-15],3));\n    s1 = (RR32(w&#91;i-2],17)) ^ (RR32(w&#91;i-2],19)) ^ (RS32(w&#91;i-2],10));\n    w&#91;i] = w&#91;i-16] + s0 + w&#91;i-7] + s1;\n  }\n  \n  a = state&#91;0];\n  b = state&#91;1];\n  c = state&#91;2];\n  d = state&#91;3];\n  e = state&#91;4];\n  f = state&#91;5];\n  g = state&#91;6];\n  h = state&#91;7];\n  \n  for(i=0;i&lt;64;i++) {\n    s0 = (RR32(a,2)) ^ (RR32(a,13)) ^ (RR32(a,22));\n    maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    t2 = s0 + maj;\n    s1 = (RR32(e,6)) ^ (RR32(e,11)) ^ (RR32(e,25));\n    ch = (e &amp; f) ^ ((~ e) &amp; g);\n    t1 = h + s1 + ch + k256&#91;i] + w&#91;i];\n    \n    h = g;\n    g = f;\n    f = e;\n    e = d + t1;\n    d = c;\n    c = b;\n    b = a;\n    a = t1 + t2;\n  }\n  \n  state&#91;0] = state&#91;0] + a;\n  state&#91;1] = state&#91;1] + b;\n  state&#91;2] = state&#91;2] + c;\n  state&#91;3] = state&#91;3] + d;\n  state&#91;4] = state&#91;4] + e;\n  state&#91;5] = state&#91;5] + f;\n  state&#91;6] = state&#91;6] + g;\n  state&#91;7] = state&#91;7] + h;\n}\n\nvoid SHA256Update(SHA256_CONTEXT *sha256, unsigned char *data, int len)\n{\n  int i,j;\n  \n  j = (int)sha256-&gt;count &amp; 63;\n  \n  sha256-&gt;count+=len;\n  \n  if((j+len)&gt;63) {\n    memcpy(&amp;sha256-&gt;buffer&#91;j],data,64-j); \/* last bytes of next block *\/\n    \n    SHA256Transform(sha256-&gt;state, sha256-&gt;buffer);\n    for (i = 64 - j ; i + 63 &lt; len; i += 64) {\n      SHA256Transform(sha256-&gt;state, &amp;data&#91;i]);\n    }\n    j = 0;\n  } else\n    i=0;\n  \n  memcpy(&amp;sha256-&gt;buffer&#91;j],&amp;data&#91;i],len-i);\n}\n\nvoid SHA256Final(unsigned char digest&#91;32], SHA256_CONTEXT *sha256)\n{\n  int i,j;\n  unsigned char filelenght&#91;8];\n  IULONG count;\n  \n  count=sha256-&gt;count &lt;&lt; 3;\n  SHA256Update(sha256,\"\\200\",1);\n  \n  while((sha256-&gt;count &amp; 63) != 56)\n    SHA256Update(sha256,\"\\0\",1);\n  \n  filelenght&#91;0]=(unsigned char)(count &gt;&gt; 56)&amp;0xff;\n  filelenght&#91;1]=(unsigned char)(count &gt;&gt; 48)&amp;0xff;\n  filelenght&#91;2]=(unsigned char)(count &gt;&gt; 40)&amp;0xff;\n  filelenght&#91;3]=(unsigned char)(count &gt;&gt; 32)&amp;0xff;\n  filelenght&#91;4]=(unsigned char)(count &gt;&gt; 24)&amp;0xff;\n  filelenght&#91;5]=(unsigned char)(count &gt;&gt; 16)&amp;0xff;\n  filelenght&#91;6]=(unsigned char)(count &gt;&gt; 8 )&amp;0xff;\n  filelenght&#91;7]=(unsigned char)(count&amp;0xff);\n  \n  SHA256Update(sha256,filelenght,sizeof(filelenght));\n  \n  for(i=0,j=0;i&lt;8;i++) {\n    digest&#91;j++]=(unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 24)&amp;0xff;\n    digest&#91;j++]=(unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 16)&amp;0xff;\n    digest&#91;j++]=(unsigned char) (sha256-&gt;state&#91;i] &gt;&gt; 8)&amp;0xff;\n    digest&#91;j++]=(unsigned char) (sha256-&gt;state&#91;i] )&amp;0xff;\n  }\n}\n\n#ifdef MAIN\n\nvoid printhex(char *name, unsigned char *digest, int len)\n{\n  int c;\n\n  fprintf(stdout,\"%s=\",name);\n  for(c=0;c&lt;len;c++) {\n    fprintf(stdout,\"%02x\",digest&#91;c]);\n  }\n  fflush(stdout);\n}\n\nint shahexdigit(int c)\n{\n  if(c&gt;='0' &amp;&amp; c&lt;='9') return(c-'0');\n  else if(c&gt;='a' &amp;&amp; c&lt;='f') return(c-'a'+10);\n  else if(c&gt;='A' &amp;&amp; c&lt;='F') return(c-'A'+10);\n  return(0);\n}\n\nvoid sha_test()\n{\n  int c,d,e,ok,allok;\n  SHA256_CONTEXT sha256;\n  unsigned char result&#91;32],*p;\n  \n  fprintf(stdout,\"%s\",sha_name);\n  fprintf(stdout,\", Context size: %ld\", sizeof(SHA256_CONTEXT));\n  fprintf(stdout,\", Hash size: 32\");\n  fprintf(stdout,\", IUBYTE size: %ld\", sizeof(IUBYTE));\n  fprintf(stdout,\", IUWORD size: %ld\", sizeof(IUWORD));\n  fprintf(stdout,\", IULONG size: %ld\", sizeof(IULONG));\n\n  struct test {\n    unsigned char *string;\n    int count;\n    unsigned char *result;\n  } tests&#91;] = {\n    { \"abc\",1,\"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\" },\n    { \"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\",1,\"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1\" },\n    { \"a\",1000000,\"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0\" },\n    { \"The quick brown fox jumps over the lazy dog\",1,\"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592\" },\n  };\n\n  allok=1;\n  for(c=0;c&lt;sizeof(tests)\/sizeof(tests&#91;0]);c++) {\n    SHA256Init(&amp;sha256);\n    for(d=0;d&lt;tests&#91;c].count;d++)\n      SHA256Update(&amp;sha256,tests&#91;c].string,strlen(tests&#91;c].string));\n    SHA256Final(result,&amp;sha256);\n    p=tests&#91;c].result;\n    d=0;\n    ok=1;\n    while(*p!='\\0') {\n      if(*p!='\\0')\n\te=shahexdigit(*p++);\n      if(*p!='\\0')\n\te=e*16+shahexdigit(*p++);\n      if(e!=result&#91;d])\n\tok=0;\n      d++;\n    }\n    if(ok) {\n      fprintf(stdout,\"\\nsha256 test \");\n      fprintf(stdout,\"string: %s\",tests&#91;c].string);\n      fprintf(stdout,\", count: %d, \",tests&#91;c].count);\n      printhex(\"tmp32\",result,sizeof(result));\n      fprintf(stdout,\", result: %s\",tests&#91;c].result);\n      fprintf(stdout,\" ok!!!!\");\n      fflush(stdout);\n    } else {\n      fprintf(stdout,\"\\nsha256 test \");\n      fprintf(stdout,\"string: %s\",tests&#91;c].string);\n      fprintf(stdout,\", count: %d, \",tests&#91;c].count);\n      printhex(\"tmp32\",result,sizeof(result));\n      fprintf(stdout,\", result: %s\",tests&#91;c].result);\n      fprintf(stdout,\" failed!!!!\");\n      fflush(stdout);\n      allok=0;\n    }\n  }\n  if(allok) {\n    fprintf(stdout,\", sha256 tests ok!!!!\\n\");\n  } else {\n    fprintf(stdout,\", sha256 tests failed!!!!\\n\");\n  }\n  fflush(stdout);\n}\n\nint main(int argc, char *argv&#91;])\n{\n  sha_test();\n}\n\n#endif<\/code><\/pre>\n\n\n\n<p>intelrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;memory.h&gt;\n\n#include \"fort.h\"\n#include \"newressu.h\"\n\n#if defined FORT_USE_RDRAND ||\t\t\t\\\n    defined FORT_USE_RDSEED\n\n\/\/ see: https:\/\/software.intel.com\/content\/www\/us\/en\/develop\/articles\/intel-digital-random-number-generator-drng-software-implementation-guide.html\n\nvoid _cpuid(unsigned int leaf, unsigned int subleaf,\n\t    unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)\n{\n  asm volatile(\"cpuid\"\n\t       : \"=a\" (*a), \"=b\" (*b), \"=c\" (*c), \"=d\" (*d)\n\t       : \"a\" (leaf), \"c\" (subleaf) );\n}\n\nint _is_cpu_vendor(unsigned char *cpuvendor)\n{\n  int ok=0;\n  unsigned int a, b, c, d;\n\n  _cpuid(0, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n\n  if(memcmp((char *)(&amp;b), cpuvendor,4)==0 &amp;&amp;\n     memcmp((char *)(&amp;d), cpuvendor+4,4)==0 &amp;&amp;\n     memcmp((char *)(&amp;c), cpuvendor+8,4)==0)\n    ok=1;\n\n  return(ok);\n}\n\n#endif\n\n#ifdef FORT_USE_RDRAND\n\nint _has_rdrand()\n{\n  int ok=0;\n  unsigned int a, b, c, d;\n\n  _cpuid(1, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((c &amp; 0x40000000) == 0x40000000) {\n    ok=1;\n  }\n\n  return(ok);\n}\n\nint _rdrand_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdrand %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdrand_bytes(int buflen, unsigned char *buf)\n{\n  int n, ret = 0;\n  unsigned long l;\n\n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdrand()) {\n    if(fort_verbose)\n      fprintf(stdout,\"Intel rdrand\");\n    ret=1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdrand()) {\n    if(fort_verbose)\n      fprintf(stdout,\"AMD rdrand\");\n    ret=1;\n  }\n  \n  if(ret) {\n    while(buflen &gt; 0) {\n      if((ret = _rdrand_long(&amp;l)) == 0) \/\/ 1 ok, 0 fail\n\tbreak;\n      if(fort_verbose)\n\tfprintf(stdout,\" %016lx\",l);\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n      memcpy(buf, (unsigned char *)&amp;l, n);\n      buf+=n;\n      buflen-=n;\n    }\n  }\n  return(ret);\n}\n\n#endif \/\/ #ifdef FORT_USE_RDRAND\n\n#ifdef FORT_USE_RDSEED\n\nint _has_rdseed()\n{\n  int ok=0;\n  unsigned int a, b, c, d;\n\n  _cpuid(7, 0, &amp;a, &amp;b, &amp;c, &amp;d);\n  if((b &amp; 0x40000) == 0x40000) {\n    ok=1;\n  }\n\n  return(ok);\n}\n\nint _rdseed_long(unsigned long *therand)\n{\n  unsigned char ret;\n\n  asm volatile(\"rdseed %0; setc %1\"\n\t       : \"=r\" (*therand), \"=qm\" (ret) );\n\n  return(int) ret;\n}\n\nint rdseed_bytes(int buflen, unsigned char *buf)\n{\n  int n, ret = 0;\n  unsigned long l;\n\n  if(_is_cpu_vendor(\"GenuineIntel\") &amp;&amp; _has_rdseed()) {\n    if(fort_verbose)\n      fprintf(stdout,\"Intel rdseed\");\n    ret=1;\n  } else if(_is_cpu_vendor(\"AuthenticAMD\") &amp;&amp; _has_rdseed()) {\n    if(fort_verbose)\n      fprintf(stdout,\"AMD rdseed\");\n    ret=1;\n  }\n\n  if(ret) {\n    while(buflen &gt; 0) {\n      int tries=0;\n      while(++tries &lt; 100) {\n\tif((ret = _rdseed_long(&amp;l)) == 1) { \/\/ 1 ok, 0 fail\n\t  break;\n\t}\n      }\n      if(ret==0)\n\tbreak;\n      if(fort_verbose) {\n\tfprintf(stdout,\" %016lx\",l);\n\tnewressu_output=1;\n      }\n      n = (buflen &lt; sizeof(l) ? buflen : sizeof(l));\n      memcpy(buf, (unsigned char *)&amp;l, n);\n      buf+=n;\n      buflen-=n;\n    }\n  }\n  return(ret);\n}\n\n#endif \/\/ #ifdef FORT_USE_RDSEED<\/code><\/pre>\n\n\n\n<p>webrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;memory.h&gt;\n#include &lt;errno.h&gt;\n\n#include &lt;openssl\/ssl.h&gt;\n#include &lt;openssl\/err.h&gt;\n\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n#include &lt;netdb.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n\n#include \"sha256.h\"\n#include \"fort.h\"\n\nextern unsigned char *procname;\nextern int fort_verbose;\n\n#include &lt;stdarg.h&gt;\n\nvoid dbs_printf(unsigned char **buf, size_t *buf_length, const unsigned char *format, ...)\n{\n  int count;\n  va_list args;;\n  \n  va_start(args, format);\n  count = vsnprintf(*buf, *buf_length, format, args) + 1;\n  va_end(args);\n  if(*buf_length &lt; count) {\n    *buf_length = count;\n    *buf = realloc(*buf, *buf_length);\n    va_start(args, format);\n    count = vsnprintf(*buf, *buf_length, format, args) + 1;\n    va_end(args);\n  }\n}\n\nint fort_connect(unsigned char *host, unsigned char *port)\n{\n  struct addrinfo hints, *res, *resp;\n  int s, status;\n  \n  memset(&amp;hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;\n  hints.ai_socktype = SOCK_STREAM;\n  hints.ai_flags = AI_PASSIVE;\n  \n  if((status = getaddrinfo(host, port, &amp;hints, &amp;res)) != 0) {\n    fprintf(stderr,\"\\n%s: getaddrinfo\", procname);\n    fprintf(stderr,\", status %d\", status);\n    fprintf(stderr,\", gai_strerror(): %s\", gai_strerror(status));\n    fprintf(stderr,\", errno %d\\n\", errno);\n    fflush(stderr);\n  }\n  \n  for(resp=res; resp!=NULL; resp = resp-&gt;ai_next) {\n    if((s = socket(resp-&gt;ai_family, resp-&gt;ai_socktype, resp-&gt;ai_protocol))&lt;0)\n      continue;\n    if(connect(s, resp-&gt;ai_addr, resp-&gt;ai_addrlen) == 0)\n      break;\n    close(s);\n  }\n\n  freeaddrinfo(res);\n\n  return(s);\n}\n\n#define aDEBUG27 2\n\nvoid fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  if((s = fort_connect(host, port))&lt;0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\"\n    \"Host: %s:%s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length=0;\n\n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port);\n  \n  if((status=write(s, msg, strlen(msg)))&lt;0) {\n    fprintf(stderr, \"\\n%s: write(), error: %d\\n\", procname, errno);\n    perror(\"write\");\n    fflush(stderr);\n  }\n\n  HashCtx ctx;\n  unsigned char buffer&#91;1024];\n\n  HashInit(&amp;ctx);\n\n  bytes=0;\n  characters=0;\n\n  while((cnt = read(s, buffer, sizeof(buffer)))&gt;0) {\n#ifdef DEBUG27\n    write(1,buffer,cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;ctx, buffer, cnt);\n    bytes+=cnt;\n    for(c=0;c&lt;cnt;c++) {\n      if(buffer&#91;c]&lt;0x80 || buffer&#91;c]&gt;0xbf)\n\tcharacters++;\n    }\n  }\n\n  hash_update_cvar(&amp;ctx);\n  HashFinal(hash, &amp;ctx);\n\n  if(fort_verbose) {\n    fprintf(stdout,\"fort_hash_http_page:\");\n    fprintf(stdout,\" %d bytes read\", bytes);\n    fprintf(stdout,\", %d characters read\", characters);\n    fprintf(stdout,\", sha256: \");\n    for(int c = 0;c &lt; HashLen; c++) {\n      fprintf(stdout,\"%02x\", hash&#91;c]);\n    }\n    fprintf(stdout,\"\\n\");\n  }\n\n  close(s);\n}\n\n#define aDEBUG49 2\n#define aDEBUG50 2\n\nvoid fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) \/\/ 202011 JariK\n{\n  int c, cnt, s, status, bytes, characters;\n\n  SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n  SSL *ssl;\n\n  SSL_library_init(); \/\/see: http:\/\/h30266.www3.hpe.com\/odl\/axpos\/opsys\/vmsos84\/BA554_90007\/ch04s03.html\n  OpenSSL_add_ssl_algorithms();\n  SSL_load_error_strings();\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSLv23_client_method()\\n\");\n#endif\n  if((method = (SSL_METHOD *)    \n      SSLv23_client_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_new()\\n\");\n#endif\n  if((ctx=SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_new()\\n\");\n#endif\n  if((ssl=SSL_new(ctx)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_new()\", procname);\n    fflush(stderr);\n  }\n\n#ifdef DEBUG49\n  fprintf(stdout,\"fort_connect()\\n\");\n#endif \n if((s = fort_connect(host, port))&lt;0) {\n    fprintf(stderr,\"\\n%s: cannot fort_connect()\", procname);\n    fprintf(stderr,\", status: %d\", s);\n    fprintf(stderr,\", errno: %d\" , errno);\n    perror(\"fort_connect\");\n    fflush(stderr);\n  }\n\n  SSL_set_fd(ssl,s);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_connect(ssl)\\n\");\n#endif \n  if((status=SSL_connect(ssl))&lt;=0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_connect()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\" , errno);\n    fprintf(stderr,\", SSL_get_error(): %d\\n\", SSL_get_error(ssl,status));\n    perror(\"SSL_connect\");\n    fflush(stderr);\n  }\n\n  unsigned char *format =\n    \"GET %s HTTP\/1.0\\r\\n\"\n    \"Host: %s:%s\\r\\n\";\n  static unsigned char *msg = NULL;\n  static size_t msg_length=0;\n\n  dbs_printf(&amp;msg, &amp;msg_length, format, page, host, port);\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_write(), msg_length:%ld, msg=\\\"%s\\\"\\n\",msg_length,msg);\n#endif \n  if((status=SSL_write(ssl, msg, strlen(msg)))&lt;0) {\n    fprintf(stderr,\"\\n%s: SSL_write()\", procname);\n    fprintf(stderr,\", status: %d\", status);\n    fprintf(stderr,\", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_write\");\n    fflush(stderr);\n  }\n  fflush(stdout);\n  \n  HashCtx hashctx;\n  unsigned char buffer&#91;2048];\n\n  HashInit(&amp;hashctx);\n\n  bytes=0;\n  characters=0;\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_read()\\n\");\n#endif\n  int bytesneeded=0, bytesheader=0, bytescontent=0;\n  \n  do {\n    cnt=SSL_read(ssl, buffer, sizeof(buffer));\n    if(cnt&lt;0) {\n      int err, err2;\n      err=SSL_get_error(ssl,cnt);\n      err2=ERR_get_error();\n\n      fprintf(stderr, \"\\n%s: cannot SSL_read()\", procname);\n      fprintf(stderr, \", retval: %d\", cnt);\n      fprintf(stderr, \", errno: %d\", errno);\n      fprintf(stderr,\", SSL_get_error() %d\", err);\n      fprintf(stderr,\", ERR_get_error() %d\\n\", err2);\n      perror(\"SSL_read\");\n      fflush(stderr);\n      break;\n    }\n\n#ifdef DEBUG50\n    write(1,buffer,cnt);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes+=cnt;\n\n    for(c=0;c&lt;cnt;c++) {\n      if(buffer&#91;c]&lt;0x80 || buffer&#91;c]&gt;0xbf)\n\tcharacters++;\n    }\n    if(bytesneeded==0) {\n      char *p;\n      p=buffer;\n      int count=0;\n      while(*p!='\\0') {\n\tif(!strncmp(p,\"\\r\\nContent-Length: \",18)) {\n\t  bytescontent=atoi(p+18);\n\t}\n\tif(!strncmp(p,\"\\r\\n\\r\\n\",4)) {\n\t  bytesheader=count;\n\t}\n\tp++;\n\tcount++;\n      }\n      bytesneeded=bytescontent+bytesheader+4;\n    }\n  } while(SSL_pending(ssl) || bytes&lt;bytesneeded);\n\n  fprintf(stdout,\"bytescontent:%d\",bytescontent);\n  fprintf(stdout,\", bytesheader:%d\",bytesheader);\n  fprintf(stdout,\", bytesneeded:%d\\n\",bytesneeded);\n  fflush(stdout);\n  \n#ifdef OLD1\n\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_read()\\n\");\n#endif \n  while((cnt=SSL_read(ssl, buffer, sizeof(buffer)))&gt;0) {\n#ifdef DEBUG49\n    fprintf(stdout,\"SSL_read() round\\n\");\n#endif \n    \n#ifdef DEBUG50\n    write(1,buffer,cnt);\n    fflush(stdout);\n#endif\n    HashUpdate(&amp;hashctx, buffer, cnt);\n    bytes+=cnt;\n    for(c=0;c&lt;cnt;c++) {\n      if(buffer&#91;c]&lt;0x80 || buffer&#91;c]&gt;0xbf)\n\tcharacters++;\n    }\n  }\n  fflush(stdout);\n  if(cnt&lt;0) {\n    fprintf(stderr, \"\\n%s: SSL_read()\", procname);\n    fprintf(stderr, \", status: %d\", status);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr,\", SSL_get_error(): %d\", SSL_get_error(ssl,status));\n    perror(\"SSL_read\");\n    fflush(stderr);\n  }\n  \n#endif\n  \n  fflush(stdout);\n\n  hash_update_cvar(&amp;hashctx);\n  HashFinal(hash, &amp;hashctx);\n\n  fprintf(stdout,\"fort_hash_https_page:\");\n  fprintf(stdout,\" %d bytes read\", bytes);\n  fprintf(stdout,\", %d characters read\", characters);\n  fprintf(stdout,\", sha256: \");\n  for(int c = 0;c &lt; HashLen; c++) {\n    fprintf(stdout,\"%02x\", hash&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n#ifdef NOTUSED\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_shutdown()\\n\");\n#endif \n  SSL_shutdown(ssl);\n#endif\n  \n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_free()\\n\");\n#endif \n  SSL_free(ssl);\n#ifdef DEBUG49\n  fprintf(stdout,\"SSL_CTX_free()\\n\");\n#endif \n  SSL_CTX_free(ctx);\n  close(s);\n}<\/code><\/pre>\n\n\n\n<p>commandrandom.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\n#include \"sha256.h\"\n#include \"fort.h\"\n\n#define DEBUG6 2 \/\/ display random data\n\nvoid fort_hash_command(unsigned char *command, unsigned char *hash)\n{\n  int c, cnt, bytes, chars;\n  FILE *fp1;\n  unsigned char buffer&#91;1024];\n\n  HashCtx hashctx;\n\n  bytes=0;\n  chars=0;\n  \n  if((fp1=popen(command, \"r\"))!=NULL) {\n    HashInit(&amp;hashctx);\n\n    if(fort_verbose) {\n      fprintf(stdout,\"fort_hash_command: %s\\n\",command);\n      fflush(stdout);\n    }\n\n    while((cnt=fread(buffer,1,sizeof(buffer),fp1))&gt;0) {\n#ifdef DEBUG6\n      if(fort_verbose)\n\tfwrite(buffer,1,cnt,stdout);\n#endif\n      HashUpdate(&amp;hashctx, buffer, cnt);\n      bytes+=cnt;\n      for(c=0;c&lt;cnt;c++) {\n\tif(buffer&#91;c]&lt;0x80 || buffer&#91;c]&gt;0xbf)\n\t  chars++;\n      }\n    }\n    pclose(fp1);\n    \n    if(fort_verbose) {\n      fprintf(stdout,\", %d bytes read\",bytes);\n      fprintf(stdout,\", %d characters read\",chars);\n    }\n    \n    hash_update_cvar(&amp;hashctx);\n    \n    HashFinal(hash, &amp;hashctx);\n\n    if(fort_verbose) {\n      fprintf(stdout,\", sha256: \");\n      for(int c = 0;c &lt; HashLen; c++) {\n\tfprintf(stdout,\"%02x\", hash&#91;c]);\n      }\n    \n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>ressu4.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;math.h&gt;\n#include &lt;sys\/time.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;unistd.h&gt;\n\n#include \"html.h\"\n#include \"dbs.h\"\n#include \"sha256.h\"\n\nunsigned char htmldigest&#91;HashLen*2+1];\n\nstatic char *programname = \"Ressu4 version 0.2 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2013-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\nchar *myport = \"5006\";\nchar *procheader = \"Ressu random numbers (3rd edition)\";\nchar *proctitle = \"Ressu random numbers\";\n\nextern char *procname;\nextern char filenamehead&#91;64];\nextern unsigned char htmlfilename&#91;64];\nextern unsigned char htmlfileextension&#91;10];\nextern unsigned char htmltime&#91;32];\nextern unsigned char htmltimeshort&#91;32];\n\nextern unsigned char useragent;\nextern unsigned char safari;\n\nint firstrun=1;\n\n#define aDEBUG8\n\nvoid ressu4_app()\n{\n  unsigned char *p;\n  unsigned char command&#91;128];\n  unsigned char buffer&#91;1024];\n  unsigned char script_file&#91;128]=\"ressu4script.html\";\n  FILE *fp1,*fp2;\n  \n  if((fp1=fopen(script_file,\"r\"))!=NULL) {\n    fclose(fp1);\n  } else {\n    if((fp1=fopen(script_file,\"w\"))!=NULL) {\n\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"; Script for ressu4 \u00a9\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h1&gt;%s&lt;\/h1&gt;\\n\",procheader);\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;p&gt;The next chapter consists of characters that\\n\");\n      fprintf(fp1,\" try to resemble throws of a 64 sided dice as closely as possible.\\n\");\n      fprintf(fp1,\" Characters have numbers from '0' to '9' (10 entries),\\n\");\n      fprintf(fp1,\" uppercase letters from 'A' to 'Z' (26 entries), lowercase letters\\n\");\n      fprintf(fp1,\" 'a' to 'z' (26 entries), '-' and '_' (2 entries).\\n\");\n      fprintf(fp1,\" Total is 10+26+26+2 = 64 values.\\n\");\n      fprintf(fp1,\" Characters are grouped into sets of 8 each. Throws\\n\");\n      fprintf(fp1,\" are random, so you cannot deduce value from\\n\");\n      fprintf(fp1,\" previous or next value(s).&lt;\/p&gt;\\n\");\n#ifdef KOK\n      fprintf(fp1,\"&lt;p&gt;Always have more than one random number generator.\\n\");\n      fprintf(fp1,\" Preferably one of them in your own program. If you have\\n\");\n      fprintf(fp1,\" to use these characters as is, add something\\n\");\n      fprintf(fp1,\" (and change something).&lt;\/p&gt;\\n\");\n#endif\n      fprintf(fp1,\"&lt;h3&gt;Newressu random numbers&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -2 -s8 -l1 -c5120 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -11 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random uppercase letters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -12 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random lowercase letters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -13 -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Random characters in number systems&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random binary digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Following binary numbers are eight bits from 0 to 255 decimal.\\n\");\n      fprintf(fp1,\" From right to left the bit multipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal.\\n\");\n      fprintf(fp1,\" So 10000000b is 128d, 11111111b is 255d, 00000010b is 2d, 00000011b is 3d etc.\\n\");\n      fprintf(fp1,\" Here d after number means of course decimal. Digit numbers, b in 2^b, vary from 0 to 7.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -b -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random octal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;These octal numbers are also from 0 to 255 decimal (0 to 377 octal).\\n\");\n      fprintf(fp1,\" From right to left octal digit multipliers are 1, 8, 64 (8^o) in decimal.\\n\");\n      fprintf(fp1,\" Here 377o is 255d, 010o is 8d, 100o is 64d.\\n\");\n      fprintf(fp1,\" Each octal digit contains 3 binary bits, and 377o can be grouped\\n\");\n      fprintf(fp1,\" in binary like this 011 111 111.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -o --lim400 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random decimal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;These decimal numbers are from 0 to 99999. From right\\n\");\n      fprintf(fp1,\" to left decimal digit multipliers are 1, 10, 100, 1000 and 10000 (10^d).&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -d -s5 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Random hexadecimal digits&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Next hexadecimal numbers are from 0000h to ffffh meaning 0 to 65535 decimal.\\n\");\n      fprintf(fp1,\" Hexadecimal digit has numbers from 0 to 9 and letters a(10),\\n\");\n      fprintf(fp1,\" b(11), c(12), d(13), e(14) and f(15). From right to left hexadecimal multipliers\\n\");\n      fprintf(fp1,\" are 1, 16, 256, 4096 decimal (16^h). Each hexadecimal digit contains 4 bits so ffffh can be\\n\");\n      fprintf(fp1,\" grouped in binary like this 1111 1111 1111 1111.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu -x -s4 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Random characters in languages&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;p&gt;The next chapters consists of random characters in various\\n\");\n      fprintf(fp1,\" languages. Most randomness is in chinese, japanese and\\n\");\n      fprintf(fp1,\" korean characters. Chinese has 20976 values per character,\\n\");\n      fprintf(fp1,\" japanese has 21158 values per character and korean has\\n\");\n      fprintf(fp1,\" 11172 values per character.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;Latin (or roman) based alphabets have characters as follows:\\n\");\n      fprintf(fp1,\" danish alphabet has 58 characters,\\n\");\n      fprintf(fp1,\" deutsch alphabet has 60 characters,\\n\");\n      fprintf(fp1,\" english has 52 characters,\\n\");\n      fprintf(fp1,\" estonian has 64 characters,\\n\");\n      fprintf(fp1,\" finnish alphabet has 58 characters,\\n\");\n      fprintf(fp1,\" french character set has 52 characters,\\n\");\n      fprintf(fp1,\" italian character set has 52 characters,\\n\");\n      fprintf(fp1,\" latvian has 66 characters,\\n\");\n      fprintf(fp1,\" lithuanian has 64 characters,\\n\");\n      fprintf(fp1,\" norwegian has 58 characters,\\n\");\n      fprintf(fp1,\" swedish has 58 characters.\\n\");\n      fprintf(fp1,\" &lt;\/p&gt;\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Chinese random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --cn -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Danish random characters&lt;\/h3&gt;\\n\");\n#ifdef KOK\n      fprintf(fp1,\"&lt;p&gt;Danish has latin letters 'a' to 'z' ('A' to 'Z')\\n\");\n      fprintf(fp1,\"and '\u00e6', '\u00f8', and '\u00e5' ('\u00c6', '\u00d8', '\u00c5').&lt;\/p&gt;\\n\");\n#endif\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\\n\");\n      fprintf(fp1,\"\/bin\/newressu --dnk -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Deutsch random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u1e9e\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00fc\u00df\\n\");\n      fprintf(fp1,\"\/bin\/newressu --deu -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;English random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --eng -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Estonian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRS\u0160Z\u017dTUVW\u00d5\u00c4\u00d6\u00dcXY\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrs\u0161z\u017etuvw\u00f5\u00e4\u00f6\u00fcxy\\n\");\n      fprintf(fp1,\"\/bin\/newressu --est -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Finnish random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\\n\");\n      fprintf(fp1,\"\/bin\/newressu --fin -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;French random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --fra -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Gothic random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --got -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Greek random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\\n\");\n      fprintf(fp1,\";\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\\n\");\n      fprintf(fp1,\"\/bin\/newressu --grc -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Italian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\\n\");\n      fprintf(fp1,\"\/bin\/newressu --ita -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Japanese random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --jp -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Korean random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\"\/bin\/newressu --kor -s8 -l1 -c1792 --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Latvian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";A\u0100BC\u010cDE\u0112FG\u0122HI\u012aJK\u0136L\u013bMN\u0145OPRS\u0160TU\u016aVZ\u017d\\n\");\n      fprintf(fp1,\";a\u0101bc\u010dde\u0113fg\u0123hi\u012bjk\u0137l\u013cmn\u0146oprs\u0161tu\u016bvz\u017e\\n\");\n      fprintf(fp1,\"\/bin\/newressu --lva -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Lithuanian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";A\u0104BC\u010cDE\u0118\u0116FGHI\u012eYJKLMNOPRS\u0160TU\u0172\u016aVZ\u017d\\n\");\n      fprintf(fp1,\";a\u0105bc\u010dde\u0119\u0117fghi\u012fyjklmnoprs\u0161tu\u0173\u016bvz\u017e\\n\");\n      fprintf(fp1,\"\/bin\/newressu --ltu -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Norwegian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c6\u00d8\u00c5\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e6\u00f8\u00e5\\n\");\n      fprintf(fp1,\"\/bin\/newressu --nor -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Russian random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\\n\");\n      fprintf(fp1,\";\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\\n\");\n      fprintf(fp1,\"\/bin\/newressu --rus -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h3&gt;Swedish random characters&lt;\/h3&gt;\\n\");\n      fprintf(fp1,\";ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c5\u00c4\u00d6\\n\");\n      fprintf(fp1,\";abcdefghijklmnopqrstuvwxyz\u00e5\u00e4\u00f6\\n\");\n      fprintf(fp1,\"\/bin\/newressu --swe -s8 -l1 -c1792 --space --lineno\\n\");\n      fprintf(fp1,\";\\n\");\n      fprintf(fp1,\"&lt;h2&gt;Technical&lt;\/h2&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;This version runs newressu new for all of the previous\\n\");\n      fprintf(fp1,\" random number chapters (25 runs), so the buffer is empty in\\n\");\n      fprintf(fp1,\" the beginning of the chapter runs.\\n\");\n      fprintf(fp1,\" This whole page is created (including randomness) after your\\n\");\n      fprintf(fp1,\" network query is received,\\n\");\n      fprintf(fp1,\" so time newressu runs is quite reasonable.&lt;\/p&gt;\\n\");\n      fprintf(fp1,\"&lt;p&gt;This version does random skips on clock material,\\n\");\n      fprintf(fp1,\" which makes it harder to guess it. Ressu skips\\n\");\n      fprintf(fp1,\" 0-255 bytes every ~1000 bytes.\\n\");\n      fprintf(fp1,\" This version also is ressu only, there is no whitening\\n\");\n      fprintf(fp1,\" or combining of other generators.&lt;\/p&gt;\\n\");\n      fclose(fp1);\n    }\n  } \/\/ if((fp1=fopen\n  if((fp1=fopen(script_file,\"r\"))!=NULL) {    \n    while(fgets(command,sizeof(command),fp1)!=NULL) {\n      if(command&#91;0]==';')\n\tcontinue;\n      else if(!strncmp(command,\"\/bin\/newressu \",14)) {\n\tif((fp2=popen(command, \"r\"))!=NULL) {\n\t  dbs_html_printf(\"&lt;code&gt;\");\n\t  while(fgets(buffer,sizeof(buffer),fp2)!=NULL) {\n#ifdef DEBUG8\n\t    fprintf(stdout,\"\\\"%s\\\"\",buffer);\n#endif\n\t    p=buffer;\n\t    while(*p!='\\0') {\n\t      if(*p!='-') \n\t\tdbs_html_printf(\"%c\",*p);\n\t      else {\n\t\tif(safari)\n\t\t  dbs_html_printf(\"&amp;#8209;\");\n\t\t\/\/dbs_html_printf(\"&amp;minus;\");\n\t\t\/\/dbs_html_printf(\"&amp;ndash;\");\n\t\t\/\/dbs_html_printf(\"&amp;hyphen;\");\n\t\t\/\/dbs_html_printf(\"&amp;#45;\");\n\t\telse\n\t\t  dbs_html_printf(\"&amp;minus;\");\n\t      }\n\t      p++;\n\t    } \/\/ while(*p!='\\0') {\n\t    \/\/dbs_html_printf(\" \");\n\t    \/\/dbs_html_printf(\"\\n\");\n\t    \/\/dbs_html_printf(\"&lt;br&gt;\");\n\t  } \/\/ while(fgets(\n\t  dbs_html_printf(\"&lt;\/code&gt;\");\n\t  fclose(fp2);\n\t} \/\/ if((fp2\n      } else { \/\/ if(!strncmp(command\n\tif(useragent)\n\t  dbs_html_printf(\"%s\",command);\n\telse if(strstr(command,\"&lt;h1&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h2&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h3&gt;\")!=NULL ||\n\t\tstrstr(command,\"&lt;h4&gt;\")!=NULL )\n\t  dbs_html_printf(\"%s\",command);\n      } \/\/ if(strncmp\n    } \/\/ while(fgets\n    fclose(fp1);\n  } \/\/ if((fp1=fopen\n  if((fp1=fopen(\"ressuoriginal.html\",\"r\"))!=NULL) {\n    while(fgets(buffer,sizeof(buffer),fp1)!=NULL)\n      if(buffer&#91;0]!=';')\n\tdbs_html_printf(\"%s\",buffer);\n    fclose(fp1);\n  }\n}\n\nvoid dba_loop()\n{\n  html_clear_all();\n  if(!strcmp(htmlfileextension,\"ico\") ||\n     !strcmp(htmlfileextension,\"png\")) {\n    dbs_html_set(0);\n    dbs_html_printf(\"HTTP\/1.0 404 Not Found\\r\\n\");\n    \/\/dbs_html_printf(\"Location: \\r\\n\");\n    \/\/dbs_html_printf(\"Server: %s\\r\\n\", programname);\n  } else {  \n    dbs_html_set(0);\n    dbs_html_printf(\"HTTP\/1.0 200 OK\\r\\n\");\n    dbs_html_printf(\"Location: \\r\\n\");\n    dbs_html_printf(\"Server: %s\\r\\n\", programname);\n    dbs_html_printf(\"Date: %s\\r\\n\", htmltime);\n    \n    dbs_html_set(1);\n    \n    dbs_html_printf(\"&lt;!doctype html&gt;\\r\\n\");\n    dbs_html_printf(\"&lt;html lang=\\\"fi\\\"&gt;\");\n    \n    dbs_html_printf(\"&lt;head&gt;\");\n    dbs_html_printf(\"&lt;meta charset=\\\"utf-8\\\"&gt;\");\n    dbs_html_printf(\"&lt;title&gt;%s&lt;\/title&gt;\",proctitle);\n    dbs_html_printf(\"&lt;meta name=\\\"author\\\" content=\\\"Jari Kuivaniemi\\\"&gt;\");\n    dbs_html_printf(\"&lt;meta name=\\\"copyright\\\" content=\\\"Jari Kuivaniemi\\\"&gt;\");\n    dbs_html_printf(\"&lt;meta name=\\\"format-detection\\\" content=\\\"telephone=no\\\"&gt;\"); \/\/ Safari\n    dbs_html_printf(\"&lt;meta name=\\\"format-detection\\\" content=\\\"telephone=no\\\"\/&gt;\"); \/\/ Safari\n    dbs_html_printf(\"&lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"&gt;\");\n    dbs_html_printf(\"&lt;\/head&gt;\");\n    \n    dbs_html_printf(\"&lt;body&gt;\");\n    \n    ressu4_app();\n\n    dbs_html_printf(\"&lt;p&gt;%s\", programname);\n    dbs_html_printf(\",  sha256(%s)\", htmldigest);\n    dbs_html_printf(\"&lt;\/p&gt;\");\n\n    dbs_html_printf(\"&lt;\/body&gt;\");\n  \n    dbs_html_printf(\"&lt;\/html&gt;\");\n  }\n}\n\nvoid dba_loop2()\n{\n  int len;\n\n  dbs_html_set(0);\n\n  len=strlen(html_get_string(1)) +\n    strlen(html_get_string(2)) +\n    strlen(html_get_string(3)) +\n    strlen(html_get_string(4)) +\n    strlen(html_get_string(5)) +\n    strlen(html_get_string(6)) +\n    strlen(html_get_string(7)) +\n    strlen(html_get_string(8));\n  log_printf(\"Content-Length: %d\\n\",len);\n  dbs_html_printf(\"Content-Length: %d\", len);\n  dbs_html_printf(\"\\r\\n\\r\\n\");\n}\n\nvoid ressu4_version()\n{\n  fprintf(stdout,\"\\n%s\", programname);\n  fprintf(stdout,\" %s\\n\", copyright);\n  fflush(stdout);\n}\n\nvoid dba_main(int argc, char *argv&#91;])\n{\n  strcat(filenamehead,procname);\n  strcat(filenamehead,myport);\n\n  ressu4_version();\n}<\/code><\/pre>\n\n\n\n<p>html.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;malloc.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ctype.h&gt;\n\n#include &lt;stdarg.h&gt;\n\n#include \"html.h\"\n\nint html_now = 0;\nunsigned char *html&#91;] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };\nint html_size&#91;] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };\n\nvoid html_set(int bufno)\n{\n  html_now=bufno;\n  if(html&#91;bufno]==NULL) {\n    html_size&#91;bufno] = 10;\n    html&#91;bufno]=malloc(html_size&#91;bufno]);\n  }\n}\n\nint html_get()\n{\n  return(html_now);\n}\n\nunsigned char *html_get_string(int bufno)\n{\n  return(html&#91;bufno]);\n}\n\nvoid html_clear()\n{\n  html_set(html_now);\n  html&#91;html_now]&#91;0]='\\0';\n}\n\nvoid html_clear_all()\n{\n  int c;\n  for(c=0;c&lt;HTML_BUFFERS;c++) {\n    html_set(c);\n    html_clear();\n  }\n}\n\nstatic void html_printf_valist(const char *format, va_list ap)\n{\n  int count;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_list ap2;\n  va_copy(ap2,ap);\n\n  count=vsnprintf(printbuf, printbuf_len, format, ap) + 1;\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf=realloc(printbuf, printbuf_len);\n    count=vsnprintf(printbuf, printbuf_len, format, ap2) + 1;\n  }\n\n  if(html_size&#91;html_now] &lt;\n     strlen(html&#91;html_now]) +\n     strlen(printbuf) + 1) {\n    html_size&#91;html_now] =\n     strlen(html&#91;html_now]) +\n     strlen(printbuf) + 1;\n    html&#91;html_now] = realloc(html&#91;html_now], html_size&#91;html_now]);\n  }\n  \n  strcpy(html&#91;html_now]+strlen(html&#91;html_now]), printbuf);\n}\n\n\nvoid html_printf(const char *format, ...)\n{\n  va_list args;\n\n  va_start(args, format);\n  html_printf_valist(format, args);\n  \/\/fprintf(stdout,format, args);\n  va_end(args);\n}\n\nvoid html_buf_printf(int bufno, const char *format, ...)\n{\n  int save_html;\n  va_list args;\n\n  save_html=html_get();\n  html_set(bufno);\n  va_start(args, format);\n  html_printf_valist(format, args);\n  va_end(args);\n  html_set(save_html);\n}\n\nint indent;\nint printedchars=0;\n\n#define aDEBUG28\n\nvoid html_out_crlf()\n{\n  if(printedchars) {\n#ifdef DEBUG28\n    fprintf(stdout,\"(%d)\",indent*8+printedchars);\n#endif\n    html_printf(\"\\n\");\n#ifdef DEBUG28\n    fprintf(stdout,\"\\n\");\n#endif\n    for(int c=0;c&lt;indent;c++) {\n      html_printf(\"\\t\");\n#ifdef DEBUG28\n      fprintf(stdout,\"\\t\");\n#endif\n    }\n    printedchars=0;\n  }\n}\n\n#define aDEBUG31 2\n\nvoid html_parse_name(int size, unsigned char *name, unsigned char **p2)\n{\n  int count;\n  unsigned char *p,*n;\n\n  p = *p2;\n  count = 0;\n  n = name;\n  while(isalpha(*p) || isdigit(*p) || *p=='!') {\n    if(++count &lt; size)\n      *n++ = *p;\n    p++;\n    count++;\n  }\n  *n = '\\0';\n\n#ifdef DEBUG31\n  fprintf(stdout,\"&#91;name:%s]\",name);\n#endif\n}\n\n#define aDEBUG36 2\n#define aDEBUG37 2\n\nvoid html_indent(unsigned char *p2)\n{\n  int space, ch, tags, tagfound, intag, inchar;\n  unsigned char *p,*q,*q2,name&#91;32],tag&#91;48];\n\n  p=p2;\n  ch=0;\n  indent=0;\n  inchar=0;\n  while(*p!='\\0') {\n    space = 0;\n    while(*p=='\\r' || *p=='\\n' || *p=='\\t' || *p==' ') {\n      p++;\n      space = 1;\n    }\n    if(!strncmp(p,\"&lt;br&gt;\",4)) {\n      p+=4;\n      html_printf(\"&lt;br&gt;\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;br&gt;\");\n#endif\n      printedchars+=4;\n      \n      while(*p=='\\r' || *p=='\\n' || *p=='\\t' || *p==' ')\n\tp++;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;nextchar:%c]\",*p);\n#endif\n      if(strncmp(p,\"&lt;\/\",2))\n\thtml_out_crlf();\n    }\n\n    if(!strncmp(p,\"&lt;\/\",2)) { \/\/ Check for end tag\n\n      q2 = p;\n      p += 2;\n      q = p;\n      html_parse_name(sizeof(name), name, &amp;q);\n      q = q2 - 1;\n      tags = 0;\n      tagfound = 0;\n\n      \/\/ Search for start tag backward\n      sprintf(tag,\"&lt;%s\", name);\n      while(q &gt;= p2) {\n        if(*q == '&lt;') {\n          if(!strncmp(tag, q, strlen(tag))) {\n#ifdef DEBUG36    \n            fprintf(stdout,\"&#91;tag:%s]\", tag);\n#endif\n            tagfound = 1;\n            break;\n          } else\n            tags++;\n        }\n        q--;\n      }\n      if(tags &amp;&amp; indent &gt; 0) {\n        indent--;\n#ifdef DEBUG36\n        fprintf(stdout,\"&#91;indent:%d]\",indent);\n        fprintf(stdout,\"&#91;tagfound:%d]\",tagfound);\n#endif\n        html_out_crlf();\n      }\n      html_printf(\"&lt;\/\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;\/\");\n#endif\n      space = 0;\n      intag = 1;\n      inchar = 0;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n      printedchars+=2;\n\n    } else if(*p=='&lt;') { \/\/ Check for start tag\n\n      p++;\n      q = p;\n      html_parse_name(sizeof(name),name,&amp;q);\n      tags = 0;\n      tagfound = 0;\n\n      \/\/ Search for end tag forward\n      sprintf(tag,\"&lt;\/%s\",name);\n      while(*q!='\\0') {\n        if(*q=='&lt;') {\n          if(!strncmp(tag, q, strlen(tag))) {\n#ifdef DEBUG36\n            fprintf(stdout,\"&#91;tag:%s]\",tag);\n#endif\n            tagfound = 1;\n            break;\n          } else\n            tags++;\n        }\n        q++;\n      }\n      html_out_crlf();\n      if(tags &amp;&amp; tagfound) {\n        indent++;\n#ifdef DEBUG36\n        fprintf(stdout,\"&#91;indent:%d]\",indent);\n        fprintf(stdout,\"&#91;tagfound:%d]\",tagfound);\n#endif\n      }\n      html_printf(\"&lt;\");\n#ifdef DEBUG36\n      fprintf(stdout,\"&lt;\");\n#endif\n      space = 0;\n      intag = 1;\n      inchar = 0;\n#ifdef DEBUG36\n      fprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n      printedchars++;\n    } else if((isprint(*p) || *p&gt;=128) &amp;&amp; *p!='\\0') {\n      if(!inchar &amp;&amp; !intag) {\n\tinchar=1;\n#ifdef DEBUG36\n\tfprintf(stdout,\"&#91;inchar:%d]\",inchar);\n#endif\n\t\/\/html_out_crlf();\n      }\n      int count=0;\n      for(q=p;(isprint(*q) || *q&gt;=128) &amp;&amp; *q!='\\0';q++) {\n\tif(*q=='\\r' || *q=='\\n' || *q=='\\t' || *q==' ')\n\t  break;\n#ifdef DEBUG36\n\tfprintf(stdout,\"%c\",*q);\n#endif\n\tcount++;\n      }\n#ifdef DEBUG36\n      fprintf(stdout,\"(%d)\",count);\n#endif\n    }\n\n    int chars = 0;\n\n    \/\/ calculate number of chars\n    q = p;\n    while((*q!='&lt;' &amp;&amp; (isprint(*q) || *q&gt;=128)) &amp;&amp; *q!='\\0') {\n      if(*q=='\\r' || *q=='\\n' || *q=='\\t' || *q==' ')\n        break;\n      if(*q&lt;0x80 || *q&gt;0xbf) \/\/ utf8 too\n        chars++;\n      if(*q=='&gt;')\n\tbreak;\n      q++;\n    }\n\n    \/\/ print line break if needed\n    if(indent*8+printedchars+chars &gt; 100 &amp;&amp; !intag) {\n      html_out_crlf(); \/\/ print nl+indent\n      space = 0;\n    }\n    \n    \/\/ print space if needed\n    if(ch != '&gt;' &amp;&amp; \/\/ no space after tag\n       *p != '&lt;' &amp;&amp; \/\/ no space before tag\n       printedchars &gt; 0 &amp;&amp;\n       space) {\n      html_printf(\" \");\n#ifdef DEBUG36\n      fprintf(stdout,\" \");\n#endif\n      space = 0;\n    }\n\n    \/\/print the string\n    while((*p != '&lt;' &amp;&amp; (isprint(*p) || *p &gt;= 128)) &amp;&amp; *p != '\\0') {\n      if(*p == '&gt;') {\n        intag = 0;\n      }\n      if(*p == '\\r' || *p == '\\n' || *p == '\\t' || *p == ' ')\n        break;\n      ch = *p;\n      html_printf(\"%c\", *p);\n#ifdef DEBUG36\n      fprintf(stdout,\"%c\",*p);\n#endif\n      printedchars++;\n      if(*p=='&gt;') {\n\tp++;\n\tbreak;\n      }\n      p++;\n    }\n#ifdef DEBUG36\n    fprintf(stdout,\"(%d)\",chars);\n#endif\n  } \/\/while(*p!='\\0')\n#ifdef DEBUG37\n  fprintf(stdout,\"%s\",html&#91;html_now]);\n#endif\n}<\/code><\/pre>\n\n\n\n<p>dbs.c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;string.h&gt;\n#include &lt;poll.h&gt;\n#include &lt;time.h&gt;\n#include &lt;ctype.h&gt;\n\n#include &lt;sys\/time.h&gt;\n\/\/#include \"db2.h\"\n#include \"sha256.h\"\n\n#include \"dbs.h\"\n\n#ifdef RESSU\n#include \"ressugen.h\"\n#endif\n\n#ifdef FORT\n#define aFORT_EVENTS 2\nstatic int fort_events = 0;\nstatic unsigned int fort_event_mode = 1;\n#endif\n#include \"fort.h\"\n\n#include \"html.h\"\n\nstatic unsigned char *copyright = \"Copyright (c) 2016-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\nstatic char *programname = \"DBS version 0.15 \u00a9\";\n\n#define html_printf dbs_html_printf\n#define IUTIME unsigned long long\nunsigned char *procname = \"dbs\";\nint callid=-1;\n\nunsigned char filenamehead&#91;16];\n\nunsigned char *htmlin;\nint htmlinlen=2048;\n\nunsigned char htmlrecvheaderlen=0;\nunsigned char *htmlrecvheader=NULL;\nunsigned char htmlrecvpayloadlen=0;\nunsigned char *htmlrecvpayload=NULL;\nunsigned char htmlsentheaderlen=0;\nunsigned char *htmlsentheader=NULL;\nunsigned char htmlsentpayloadlen=0;\nunsigned char *htmlsentpayload=NULL;\nunsigned char htmlmethod&#91;10];\nunsigned char htmlpath&#91;128];\nunsigned char htmlversion&#91;32];\nunsigned char htmlfilename&#91;64];\nunsigned char htmlfileextension&#91;10];\nunsigned char htmlhost&#91;32];\nunsigned char htmluseragent&#91;1024];\nunsigned char htmlcookie&#91;1024];\nunsigned char htmlsessionid&#91;33];\nunsigned char htmltimeshort&#91;32];\nunsigned char htmltime&#91;32];\nunsigned char *htmlparams=NULL;\nunsigned char htmldigest&#91;HashLen*2+1];\nunsigned char htmlmode&#91;10];\nunsigned char htmlip&#91;32];\nunsigned char htmlsslcipher&#91;64];\nunsigned char htmlhostname&#91;64];\nunsigned char htmlport&#91;10];\nunsigned char htmllanguage&#91;10];\nunsigned char htmluseconds&#91;10];\nunsigned char htmlprevminutes&#91;32];\nunsigned char useragent=0;\nunsigned char chrome=0;\nunsigned char edg=0;\nunsigned char firefox=0;\nunsigned char ipad=0;\nunsigned char iphone=0;\nunsigned char flaglinux=0;\nunsigned char safari=0;\n\n#define USE_SEMAPHORES 2\n\nvoid dump_string(FILE *fp1, unsigned char *p)\n{\n  fprintf(stdout,\"{\");\n  while(*p != '\\0') {\n    if(*p == '\\\\')\n      fprintf(fp1,\"\\\\\\\\\");\n    else if(isprint(*p))\n      fprintf(fp1,\"%c\", *p);\n    else\n      fprintf(fp1,\"\\\\%02x\", *p);\n    p++;\n  }\n  fprintf(stdout,\"}\");\n}\n\nstatic int dbs_parse_hex1(unsigned char **str) \/* 20131003 JariK *\/\n{\n  unsigned char *p;\n  int digit;\n\n  p=*str;\n  digit=0;\n  if(*p &gt;= 'a' &amp;&amp; *p &lt;= 'f')\n    digit = *p - 'a' + 10, p++;\n  else if(*p &gt;= 'A' &amp;&amp; *p &lt;= 'F')\n    digit = *p - 'A' + 10, p++;\n  else if(*p &gt;= '0' &amp;&amp; *p &lt;= '9')\n    digit = *p - '0', p++;\n  else digit = -1;\n\n  *str = p;\n  return(digit);\n}\n\nstatic int dbs_parse_html_string(int stringlen, unsigned char *string, unsigned char **html)\n{\n  int c,d, count, ok;\n  unsigned char *s=string;\n  unsigned char *h=*html;\n\n  ok = 0;\n  count = 0;\n  \n  while(isalnum(*h) || *h=='%' || *h=='+'\n\t|| *h == '-' || *h == '_' || *h == '.'\n\t|| *h==',' || *h == '*') {\n    ok = 1;\n    if(*h == '%') {\n      h++;\n      if((c=dbs_parse_hex1(&amp;h)) &gt;= 0) {\n\tif((d=dbs_parse_hex1(&amp;h)) &gt;= 0) {\n\t  c = c * 16 + d;\n\t} else\n\t  c = c;\n      } else\n\tc = 64;\n      if(++count &lt; stringlen) {\n\tif(c == 0x22)\n\t  *s++ = '\\'';\n\telse\n\t  *s++ = c;\n      }\n    } else if(*h == '+') {\n      if(++count &lt; stringlen)\n\t*s++ = ' ';\n      h++;\n    } else {\n      if(++count &lt; stringlen)\n\t*s++ = *h;\n      h++;\n    }\n  }\n  *s = '\\0';\n  *html = h;\n\n  return(ok);\n}\n\n#include &lt;stdarg.h&gt;\n\nint dbs_html_get_string(unsigned char *string,unsigned char **str,int len)\n{\n  int c, d, ok, count;\n  unsigned char *p, *n;\n\n  n = string;\n  p = *str;\n  ok = 0;\n\n  count = 0;\n  while(isalnum(*p) || *p == '%'|| *p == '+'\n\t|| *p == '-' || *p == '_' || *p == '='\n\t|| *p=='&amp;' || *p=='.' || *p=='*') {\n    ok = 1;\n    if(*p == '%') {\n      p++;\n      if((c = dbs_parse_hex1(&amp;p)) &gt;= 0) {\n\tif((d = dbs_parse_hex1(&amp;p)) &gt;= 0) {\n\t  c = c * 16 + d;\n\t} else\n\t  c = c;\n      } else\n\tc = 64;\n      if(count++ &lt; len)\n\t*n++ = c;\n    } else if(*p == '+') {\n      if(count++ &lt; len)\n\t*n++ = ' ';\n      p++;\n    } else {\n      if(count++ &lt; len)\n\t*n++ = *p++;\n      else\n\tp++;\n    }\n  }\n  *n = '\\0';\n  *str = p;\n\n  return(ok);\n}\n\nint dbs_parse_html_parameter(int namelen, unsigned char *name, int valuelen,unsigned char *value, unsigned char **s)\n{\n  if(dbs_parse_html_string(namelen, name, s) == 0)\n    return(0);\n  if((**s) == '=')\n    (*s)++;\n  dbs_parse_html_string(valuelen, value, s);\n#ifdef OLD1\n  if(dbs_parse_html_string(valuelen, value, s) == 0)\n    return(0);\n#endif\n  if(**s == '&amp;')\n    (*s)++;\n  \n  return(1);\n}\n\nint dbs_get_parameter(char *name, int valuelen, unsigned char *value)\n{\n  int ok;\n  unsigned char name2&#91;32];\n  unsigned char *h=htmlparams;\n\n  value&#91;0] = '\\0';\n  ok = 0;\n\n  while(*h != '\\0') {\n    dbs_parse_html_parameter(sizeof(name2), name2, valuelen, value, &amp;h);\n    if(!strcmp(name,name2)) {\n      ok = 1;\n      break;\n    }\n  }\n\n  if(ok == 0)\n    value&#91;0] = '\\0';\n  \n  return(ok);\n}\n\nstatic unsigned long dbs_getseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec);\n}\n\n#define aDEBUG11 2\n\nstatic unsigned char *dbs_html_get_request_line(unsigned char *name, int lenbuffer, unsigned char *buffer)\n{\n  int len;\n  unsigned char *p, *q, tag&#91;32];\n\n  p = htmlin;\n\n#ifdef DEBUG11\n  fprintf(stdout,\"Data:\");\n  dump_string(stdout,p);\n  fprintf(stdout,\"\\n\");\n#endif\n  \n  sprintf(tag,\"\\r\\n%s:\",name);\n  while(*p != '\\0') {\n    if(!strncmp(p, tag, strlen(tag))) {\n      p += strlen(tag);\n      while(isblank(*p))\n\tp++;\n      q = buffer;\n      len = 0;\n      while(*p != '\\r' &amp;&amp; *p != '\\n' &amp;&amp; *p != '\\0') {\n\tif(++len &lt; lenbuffer)\n\t  *q++ = *p;\n\tp++;\n      }\n      *q = '\\0';\n      return(buffer);\n    }\n    if(*p != '\\0')\n      p++;\n  }\n  return(NULL);\n}\n\nstatic void dbs_html_get_request_line_num(unsigned char *name, int lenbuffer, unsigned char *buffer)\n{\n  unsigned char *p;\n\n  if((p = dbs_html_get_request_line(name,lenbuffer,buffer)) == NULL)\n    sprintf(buffer,\"0\");\n#ifdef OLD1\n  else {\n    int len = 0;\n    unsigned char *n = buffer;\n    while(isdigit(*p)) {\n      if(++len &lt; lenbuffer)\n        *n++ = *p;\n      p++;\n    }\n    *n = '\\0';\n  }\n#endif\n}\n\nvoid dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value)\n{\n  int len;\n  unsigned char *p, *n;\n\n  value&#91;0] = '\\0';\n  \n  p = htmlcookie;\n  \n  while(*p != '\\0') {\n    while(isblank(*p))\n      p++;\n    if(!strncmp(p,name,strlen(name))) {\n      p += strlen(name);\n      while(isblank(*p))\n        p++;\n      if(*p == '=')\n        p++;\n      while(isblank(*p))\n        p++;\n      n = value;\n      len = 0;\n      while(*p != ';' &amp;&amp; isprint(*p)) {\n        if(++len &lt; valuelen)\n          *n++ = *p;\n        p++;\n      }\n      *n = '\\0';\n      return;\n    }\n    while(*p != ';' &amp;&amp; *p != '\\n' &amp;&amp; *p != '\\0')\n      p++;\n    if(*p == ';')\n      p++;\n    while(isblank(*p))\n      p++;\n  }\n}\n\nstatic void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2)\n{\n  int len;\n  unsigned char *p;\n\n  p=*p2;\n  len=0;\n  while(*p!='\\0' &amp;&amp; !isblank(*p) &amp;&amp; *p!='\\n' &amp;&amp; *p!='\\r') {\n    if(++len &lt; buflen) {\n      *buf++ = *p;\n    }\n    p++;\n  }\n  *buf='\\0';\n\n  while(isblank(*p))\n    p++;\n\n  *p2 = p;\n}\n\nstatic void dbs_html_parse_filename(int buflen, char *buf, unsigned char *p)\n{\n  int len;\n  unsigned char *n;\n\n  len = 0;\n  n = buf;\n\n  while(*p != '\\0') {\n    if(*p == '\/') {\n      n = buf;\n      len = 0;\n    } else {\n      if(++len &lt; buflen)\n        *n++ = *p;\n    }\n    p++;\n  }\n  *n = '\\0';\n}\n\nstatic void dbs_html_parse_extension(int buflen, char *buf, unsigned char *p)\n{\n  int len;\n  unsigned char *n;\n\n  len = 0;\n  n = buf;\n\n  while(*p != '\\0') {\n    if(*p == '.') {\n      n = buf;\n      len = 0;\n    } else {\n      if(++len &lt; buflen)\n        *n++ = *p;\n    }\n    p++;\n  }\n  *n = '\\0';\n}\n\nstatic unsigned char *dbs_html_get_params()\n{\n  int ok = 0;\n  unsigned char *p = htmlin;\n\n  while(*p != '\\0') {\n    if(!strncmp(p,\"\\r\\n\\r\\n\",4)) {\n      p += 4;\n      ok = 1;\n      break;\n    }\n    p++;\n  }\n\n  if(ok)\n    return(p);\n  else\n    return(NULL);\n}\n\n#include &lt;stdarg.h&gt;\n\nunsigned char *logbuf=NULL;\nint logbuf_len=0;\n\nvoid log_clear()\n{\n  if(logbuf != NULL)\n    logbuf&#91;0] = '\\0';\n}\n\nvoid log_free()\n{\n  if(logbuf != NULL) {\n    free(logbuf);\n    logbuf_len = 0;\n    logbuf = NULL;\n  }\n}\n\n#define aDEBUG20 2\n#define aDEBUG21 2\n\nvoid log_printf(const char *format, ...)\n{\n  int count,size;\n  va_list args;\n  static char *printbuf=NULL;\n  static int printbuf_len=0;\n\n  va_start(args, format);\n  count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n  va_end(args);\n\n  if(printbuf_len &lt; count) {\n    printbuf_len = count;\n    printbuf=realloc(printbuf, printbuf_len);\n    va_start(args, format);\n    count=vsnprintf(printbuf, printbuf_len, format, args) + 1;\n    va_end(args);\n  }\n\n#ifdef DEBUG20\n  fprintf(stdout,\"\\n%p %d %s %p %d\",\n\t  printbuf, printbuf_len, printbuf, logbuf, logbuf_len);\n#endif\n\n  size=(logbuf==NULL? 0:strlen(logbuf))+count;\n  if(logbuf_len&lt;size) {\n    unsigned char *temp=logbuf;\n    logbuf_len = size;\n    logbuf = realloc(logbuf, logbuf_len);\n    if(temp == NULL)\n      logbuf&#91;0] = '\\0';\n  }\n\n#ifdef DEBUG21\n  fprintf(stdout,\"\\n%p %d %s\",\n\t  logbuf, logbuf_len, logbuf);\n#endif\n  strcat(logbuf, printbuf);\n}\n\nvoid log_dump_string(unsigned char *p)\n{\n  while(*p != '\\0') {\n    if(*p == '\\\\')\n      log_printf(\"\\\\\\\\\");\n    else if(isprint(*p) || *p == '\\r' || *p == '\\n')\n      log_printf(\"%c\",*p);\n    else\n      log_printf(\"\\\\%02x\",*p);\n    p++;\n  }\n}\n\nstatic void dbs_add_end_new_str(char *filename, char *string)\n{\n  int ok;\n  char buffer&#91;256];\n  FILE *fp1;\n\n  ok = 0;\n  if((fp1 = fopen(filename,\"r\")) != NULL) {\n    while(fgets(buffer,sizeof(buffer),fp1) != NULL) {\n      buffer&#91;strlen(buffer)-1] = '\\0';\n      if(!strcmp(buffer,string)) {\n\tok = 1;\n\tbreak;\n      }\n    }\n    fclose(fp1);\n  }\n  if(!ok) {\n    if((fp1 = fopen(filename,\"a\")) != NULL) {\n      fprintf(fp1,\"%s\\n\", string);\n      fclose(fp1);\n    }\n  }\n}\n\n#define aDEBUG25 2\n\nvoid dba_loop();\nvoid dba_loop2();\n\nstatic void dbs_run_loop()\n{  \n  unsigned char *p;\n\n  p=htmlin;\n  dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&amp;p);\n  dbs_html_parse_string(sizeof(htmlpath), htmlpath, &amp;p);\n  dbs_html_parse_string(sizeof(htmlversion), htmlversion, &amp;p);\n  dbs_html_parse_filename(sizeof(htmlfilename), htmlfilename, htmlpath);\n  dbs_html_parse_extension(sizeof(htmlfileextension), htmlfileextension, htmlfilename);\n  \n  htmlparams = dbs_html_get_params();\n  if(htmlparams == NULL)\n    htmlparams = \"\";\n\n  if(dbs_html_get_request_line(\"Host\", sizeof(htmlhost), htmlhost) == NULL)\n    htmlhost&#91;0] = '\\0';\n  \n  if(dbs_html_get_request_line(\"User-Agent\", sizeof(htmluseragent), htmluseragent) == NULL)\n    htmluseragent&#91;0] = '\\0';\n\n  if(dbs_html_get_request_line(\"Cookie\", sizeof(htmlcookie), htmlcookie)==NULL)\n    htmlcookie&#91;0] = '\\0';\n  \n  chrome = 0;\n  edg = 0;\n  firefox = 0;\n  ipad = 0;\n  iphone = 0;\n  flaglinux = 0;\n  safari = 0;\n\n  useragent=0;\n\n  if(htmluseragent&#91;0] != '\\0')\n    useragent = 1;\n\n  unsigned char *p2 = htmluseragent;\n\n  log_printf(\", useragent\");\n\n  p2=p;\n  while(*p2 != '\\r' &amp;&amp; *p2 != '\\n') {\n    if(!strncmp(p2,\"Chrome\",6)) {\n      chrome = 1;\n      log_printf(\", chrome\");\n    }\n    if(!strncmp(p2,\"Edg\",6)) {\n      edg = 1;\n      log_printf(\", Edg\");\n    }\n    if(!strncmp(p2,\"Firefox\",6)) {\n      firefox = 1;\n      log_printf(\", firefox\");\n    }\n    if(!strncmp(p2,\"iPad\",4)) {\n      ipad = 1;\n      log_printf(\", ipad\");\n    }\n    if(iphone==0 &amp;&amp; !strncmp(p2,\"iPhone\",6)) {\n      iphone = 1;\n      log_printf(\", iphone\");\n    }\n    if(!strncmp(p2,\"Linux\",5)) {\n      flaglinux = 1;\n      log_printf(\", linux\");\n    }\n    if(!strncmp(p2,\"Safari\",6)) {\n      safari = 1;\n      log_printf(\", safari\");\n    }\n    p2++;\n  }\n\n  log_printf(\"\\n\");\n\n  html_clear_all();\n  \n  dba_loop();\n\n#ifdef DEBUG25\n  log_printf(\"\\nhtml prettyprinter\");\n#endif\n  \n#ifdef DEBUG25\n  log_printf(\"\\nbuffers1:\");\n  for(int c = 0; c &lt; HTML_BUFFERS; c++) { \n    log_printf(\" %d:%ld\", c, strlen(html_get_string(c)));\n  }\n  log_printf(\"\\n\");  \n#endif\n  \n  for(int c = 1; c &lt; HTML_BUFFERS-2; c++) {\n    p = html_get_string(c);\n    dbs_html_set(HTML_BUFFERS - 2);\n    html_printf(\"%s\", p);\n    dbs_html_set(c);\n    html_clear();\n  }\n  \n#ifdef DEBUG25\n  log_printf(\"\\nbuffers2:\");\n  for(int c = 0; c &lt; HTML_BUFFERS; c++) { \n    log_printf(\" %d:%ld\",c,strlen(html_get_string(c)));\n  }\n  log_printf(\"\\n\");  \n#endif\n  \n  p = html_get_string(HTML_BUFFERS-2);\n  dbs_html_set(HTML_BUFFERS - 1);\n  html_indent(p);\n  dbs_html_set(HTML_BUFFERS - 2);\n  html_clear();\n  \n#ifdef DEBUG25\n  log_printf(\"\\nbuffers3:\");\n  for(int c = 0; c &lt; HTML_BUFFERS; c++) { \n    log_printf(\" %d:%ld\",c, strlen(html_get_string(c)));\n  }\n  log_printf(\"\\n\");  \n#endif\n  \n#ifdef DEBUG25\n  log_printf(\"html prettyprinter done.\\n\");\n#endif\n  \n  dba_loop2();\n}\n\n#define aDEBUG34 2\n#define aDEBUG31 2\n\nstatic void dbs_run_critical_port()\n{\n  FILE *fp1;\n  char filename&#91;128];\n  char filename2&#91;128];\n\n  sprintf(filename,\"%stimelog.log\", filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\", filename);\n#endif\n  if((fp1 = fopen(filename,\"a\")) != NULL) {\n    fprintf(fp1,\"%s, ip=\\\"%s\\\"\\n\", htmltimeshort, htmlip);\n    fclose(fp1);\n  }\n  \n  sprintf(filename,\"%sips.log\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  dbs_add_end_new_str(filename, htmlip);\n\n  sprintf(filename,\"%shostname.log\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  dbs_add_end_new_str(filename, htmlhostname);\n\n  if(htmlsslcipher&#91;0] != '\\0') {\n    sprintf(filename,\"%sciphers.log\",filenamehead);\n#ifdef DEBUG34\n    fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n    dbs_add_end_new_str(filename, htmlsslcipher);\n  }\n\n  if(htmluseragent&#91;0] != '\\0') {\n    sprintf(filename,\"%suseragent.log\",filenamehead);\n#ifdef DEBUG34\n    fprintf(stdout,\"Writing %s\\n\", filename);\n#endif\n    dbs_add_end_new_str(filename,htmluseragent);\n  }\n\n  sprintf(filename2,\"%scallid.dat\", filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Reading %s\\n\", filename2);\n#endif\n  if((fp1 = fopen(filename2, \"r\")) != NULL) {\n    unsigned char buffer16&#91;16];\n    fgets(buffer16, sizeof(buffer16), fp1);\n    callid = atoi(buffer16);\n    fclose(fp1);\n  } else {\n    callid = 0;\n  }\n  \n  log_printf(\"callid:%d\\n\",callid);\n  sprintf(filename,\"%shtml.log\",filenamehead);\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename);\n#endif\n  if((fp1 = fopen(filename, \"a\")) != NULL) {\n    fprintf(fp1,\"htmltime: \\\"%s\\\", htmltimeshort: \\\"%s\\\", ip=\\\"%s\\\", callid=\\\"%d\\\"\\n\",\n\t    htmltime, htmltimeshort, htmlip, callid);\n    fprintf(fp1,\"%s\\n\", htmlin);\n    for(int c = 0; c &lt; HTML_BUFFERS; c++) {\n#ifdef DEBUG31\n      fprintf(stdout,\"%d\", c);\n      fprintf(stdout,\" %p\", html_get_string(c));\n      if(html_get_string(c) != NULL)\n\tfprintf(stdout,\"%s\", html_get_string(c));\n#endif\n      if(html_get_string(c) != NULL &amp;&amp;\n\t strlen(html_get_string(c)) &gt; 0) {\n\tfprintf(fp1,\"%d: %s\\n\", c, html_get_string(c));\n      }\n    }\n    fclose(fp1);\n  }\n  \n  callid++; \/\/ next call id\n#ifdef DEBUG34\n  fprintf(stdout,\"Writing %s\\n\",filename2);\n#endif\n  if((fp1=fopen(filename2, \"w\")) != NULL) {\n    fprintf(fp1,\"%d\\n\", callid);\n    fclose(fp1);\n  }\n}\n\nstruct lfield {\n  unsigned char *name;\n  int valuetype;\n  unsigned char *value;\n  int size;\n} lfields&#91;] = {\n  { \"procname\", 1, (unsigned char *)&amp;procname, 32 },\n  { \"timeshort\", 0, htmltimeshort, sizeof(htmltimeshort) },\n  { \"time\", 0, htmltime, sizeof(htmltime) },\n  { \"hostname\", 0, htmlhostname, sizeof(htmlhostname) },\n  { \"host\", 0, htmlhost, sizeof(htmlhost) },\n  { \"useragent\", 0, htmluseragent, sizeof(htmluseragent) },\n  { \"method\", 0, htmlmethod, sizeof(htmlmethod) },\n  { \"path\", 0, htmlpath, sizeof(htmlpath) },\n  { \"version\", 0, htmlversion, sizeof(htmlversion) },\n  { \"filename\", 0, htmlfilename, sizeof(htmlfilename) },\n  { \"fileextension\", 0, htmlfileextension, sizeof(htmlfileextension) },\n  { \"cookie\", 0, htmlcookie, sizeof(htmlcookie) },\n  { \"sessionid\", 0, htmlsessionid, sizeof(htmlsessionid) },\n  { \"params\", 1, (unsigned char *)&amp;htmlparams, 0 },\n  { \"recvheader\", 1, (unsigned char *)&amp;htmlrecvheader, sizeof(htmlrecvheader) },\n  { \"recvpayload\", 1, (unsigned char *)&amp;htmlrecvpayload, sizeof(htmlrecvpayload) },\n  { \"sentheader\", 1, (unsigned char *)&amp;htmlsentheader, sizeof(htmlsentheader) },\n  { \"sentpayload\", 1, (unsigned char *)&amp;htmlsentpayload, sizeof(htmlsentpayload) },\n  { \"digest\", 0, htmldigest, sizeof(htmldigest) },\n  { \"mode\", 0, htmlmode, sizeof(htmlmode) },\n  { \"ip\", 0, htmlip, sizeof(htmlip) },\n  { \"sslcipher\", 0, htmlsslcipher, sizeof(htmlsslcipher) },\n  { \"port\", 0, htmlport, sizeof(htmlport) },\n  { \"language\", 0, htmllanguage, sizeof(htmllanguage) },\n  { \"useconds\", 0, htmluseconds, sizeof(htmluseconds) },\n  { \"prevminutes\", 0, htmlprevminutes, sizeof(htmlprevminutes) },\n};\n\nstruct lfile {\n  unsigned char *query;\n} lfiles&#91;] = {\n  { \"\" },\n};\n\n#define aDEBUG35 2\n#define VALUEUTF8 2\n\nint db4_compile_field(int buflength, unsigned char *buf, unsigned char *name)\n{\n  int size=0;\n  unsigned char *value=NULL;\n\n  for(int c = 0; c &lt; sizeof(lfields) \/ sizeof(struct lfield); c++) {\n    if(!strcmp(name, lfields&#91;c].name)) {\n      if(lfields&#91;c].valuetype == 0) {\n\tvalue = lfields&#91;c].value;\n\tbreak;\n      } else if(lfields&#91;c].valuetype == 1) {\n\tvalue = *((unsigned char **)lfields&#91;c].value);\n\tbreak;\n      }\n\n    }\n  }\n  size = 7 + strlen(name);\n  if(value != NULL) {\n    unsigned char *p;\n    p = value;\n    while(*p != '\\0') {\n      if(*p == '\"')\n\tsize+=2;\n      else if(*p=='\\\\')\n\tsize+=2;\n#ifdef VALUEUTF8\n      else if(isprint(*p) || *p&gt;=0x80)\n#else\n      else if(isprint(*p))\n#endif\n\tsize++;\n      else\n\tsize+=3;\n      p++;\n    }\n  }\n  if(size &lt; buflength) {\n    strcat(buf,\"'\");\n    strcat(buf,name);\n    strcat(buf,\"' = \\\"\");\n    if(value != NULL) {\n      unsigned char *p;\n      p=value;\n      while(*p != '\\0') {\n\tif(*p == '\"') {\n\t  unsigned char char3&#91;3];\n\t  sprintf(char3,\"\\\\\\\"\");\n\t  strcat(buf,char3);\n\t} else if(*p == '\\\\') {\n\t  strcat(buf,\"\\\\\\\\\");\n#ifdef VALUEUTF8\n\t} else if(isprint(*p) || *p &gt;= 0x80) {\n#else\n\t} else if(isprint(*p)) {\n#endif\n\t  unsigned char char2&#91;2];\n\t  sprintf(char2,\"%c\",*p);\n\t  strcat(buf, char2);\n\t} else {\n\t  unsigned char char4&#91;4];\n\t  sprintf(char4,\"\\\\%02x\",*p);\n\t  strcat(buf, char4);\n\t}\n\tp++;\n      }\n#ifdef DEBUG35\n      unsigned char *q=buf;\n      while(*q != '\\0') {\n\tif(isprint(*q))\n\t  fprintf(stdout,\"%c\",*q);\n\telse\n\t  fprintf(stdout,\"\\\\%02x\",*q);\n\tq++;\n      }\n#endif\n    }\n    strcat(buf,\"\\\"\");\n  }\n  return(size);\n}\n\nint db4_compile_set(int buflen, unsigned char *buf2)\n{\n  int size, count, first=1;\n  unsigned char *buf = buf2;\n  size=0;\n  if(buflen &gt; 0)\n    buf&#91;0]='\\0';\n  \n  for(int c = 0; c &lt; sizeof(lfields) \/ sizeof(struct lfield); c++) {\n    count = 0;\n    if(!first) {\n      if(2 &lt; buflen)\n\tstrcat(buf,\", \");\n      count += 2;\n    }\n    count += db4_compile_field(buflen,buf,lfields&#91;c].name);\n    buf += count;\n    buflen -= count;\n    size += count;\n    first = 0;\n  }\n  \n  return(size);\n}\n\n#define DEBUG39\n\nstatic void dbs_run_critical_all() {\n  int count, buflen=0;\n  unsigned char *buf=NULL;\n\n#ifdef DEBUG39\n  fprintf(stdout,\"db4_compile_set() %d\\n\",buflen);\n  fflush(stdout);\n#endif\n  count = db4_compile_set(buflen,buf) + 1;\n    \n  if(buflen &lt; count) {\n    buflen = count;\n    buf = realloc(buf,buflen);\n#ifdef DEBUG39\n    fprintf(stdout,\"db4_compile_set() %d\\n\",buflen);\n    fflush(stdout);\n#endif\n    count = db4_compile_set(buflen,buf)+1;\n  }\n  FILE *fp1;\n  if((fp1 = fopen(\"dbs.skk\",\"a\")) != NULL) {\n    fprintf(fp1,\"%s\\n\",buf);\n    fclose(fp1);\n  }\n  fprintf(stdout,\"%s(%ld)\\n\",buf,strlen(buf));\n  fflush(stdout);\n  \/\/for(int c=0;c&lt;sizeof(lfiles)\/sizeof(struct lfile);c++) {\n  \/\/fprintf(stdout,\"%s\",lfiles&#91;c].filename);\n  \/\/}\n}\n\n#include &lt;errno.h&gt;\n#include &lt;semaphore.h&gt;\n#include &lt;fcntl.h&gt;\n\nunsigned char semname&#91;32], sem2name&#91;32];  \nsem_t *mutex, *mutex2;\nextern char *myport;\n\nvoid dbs_open_semaphores()\n{\n  \/\/ semaphore for critical_port\n      \n  sprintf(semname,\"dbssem%s\", myport);\n  \n  if(sem_unlink(semname) == 0) {\n    fprintf(stdout,\"%s: previous semaphore %s removed\\n\", procname, semname);\n  }\n#ifdef DEBUG42\n  fprintf(stdout,\"sem_open()\\n\");\n#endif\n  if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {\n    fprintf(stderr,\"\\n%s: cannot sem_open()\", procname);\n    fprintf(stderr,\" errno %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_open\");\n  }\n  \n  \/\/ semaphore for critical_all\n  \n  sprintf(sem2name,\"dbssem\");\n  \n  if(sem_unlink(sem2name) == 0) {\n    fprintf(stdout,\"%s: previous semaphore %s removed\\n\", procname, sem2name);\n  }\n#ifdef DEBUG42\n  fprintf(stdout,\"sem_open()\\n\");\n#endif\n  if((mutex2 = sem_open(sem2name, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {\n    fprintf(stderr,\"\\n%s: cannot sem_open()\", procname);\n    fprintf(stderr,\" errno %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_open\");\n  }\n}\n\nvoid dbs_close_semaphores()\n{\n  sem_unlink(semname);\n  sem_close(mutex);\n}\n\nvoid dbs_run_critical_sections()\n{\n#ifdef USE_SEMAPHORES\n      \n  fprintf(stdout,\"locking port semaphore(child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"sem_wait()\\n\");\n  fflush(stdout);\n#endif\n  if(sem_wait(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_wait()\", procname);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_wait\");\n  }\n  \n  fprintf(stdout,\"critical section (child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"dbs_run_critical_port()\\n\");\n  fflush(stdout);\n#endif\n  dbs_run_critical_port();\n  \n#ifdef USE_SEMAPHORES\n  \n  fprintf(stdout,\"end critical section (child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"sem_post()\\n\");\n#endif\n  if(sem_post(mutex) == -1) {\n    fprintf(stderr, \"%s: cannot sem_post()\", procname);\n    fprintf(stderr, \", errno: %d\\n\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    perror(\"sem_post\");\n  }\n  \n  fprintf(stdout,\"release port semaphore(child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  \n  fprintf(stdout,\"locking all semaphore(child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"sem_wait()\\n\");\n  fflush(stdout);\n#endif\n  if(sem_wait(mutex2) == -1) {\n    fprintf(stderr, \"%s: cannot sem_wait()\", procname);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"sem_wait\");\n  }\n  \n  fprintf(stdout,\"critical section (child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n#endif\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"dbs_run_critical_all()\\n\");\n  fflush(stdout);\n#endif\n  dbs_run_critical_all();\n  \n#ifdef USE_SEMAPHORES\n  \n  fprintf(stdout,\"end critical section (child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"sem_post()\\n\");\n#endif\n  if(sem_post(mutex2) == -1) {\n    fprintf(stderr, \"%s: cannot sem_post()\", procname);\n    fprintf(stderr, \", errno: %d\\n\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    perror(\"sem_post\");\n  }\n  \n  fprintf(stdout,\"release all semaphore(child)\");\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n}\n\n#include &lt;openssl\/ssl.h&gt;\n#include &lt;openssl\/err.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/socket.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;netinet\/in.h&gt;\n#include &lt;arpa\/inet.h&gt;\n\/* See: http:\/\/h41379.www4.hpe.com\/doc\/83final\/ba554_90007\/ch04s03.html *\/\n\n#include &lt;netdb.h&gt;\n\n#define backlog 64\n\nint s,news;\nchar cert_file&#91;128] = \"fullchain.pem\";\nchar privatekey_file&#91;128] = \"privkey.pem\";\n\n#define DEBUG42 2\n\nstatic int server_getaddrinfo(unsigned char *myport, struct addrinfo **res)\n{\n  int status;\n  struct addrinfo hints;\n\n  memset(&amp;hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;                   \n  hints.ai_socktype = SOCK_STREAM;\n  hints.ai_flags = AI_PASSIVE;\n\n#ifdef DEBUG42\n  fprintf(stdout,\"getaddrinfo()\\n\");\n#endif\n  if ((status = getaddrinfo(NULL, myport, &amp;hints, res)) != 0) {\n    fprintf(stderr, \"\\n%s: getaddrinfo error: %s\",\n            procname, gai_strerror(status));\n    fprintf(stderr, \", error code %d\\n\", status);\n    \/\/fflush(stderr);\n  }\n  return(status);\n}\n\nstatic int server_socket(struct addrinfo *res)\n{\n  int s;\n\n#ifdef DEBUG42\n  fprintf(stdout,\"socket()\\n\");\n#endif\n  if((s = socket(res-&gt;ai_family, res-&gt;ai_socktype, res-&gt;ai_protocol)) == -1) {\n    fprintf(stderr, \"%s: socket()\", procname);\n    fprintf(stderr, \", errno: %d\", errno);\n    fprintf(stderr, \"(%s)\", strerror(errno));\n    fprintf(stderr,\"\\n\");\n    perror(\"socket\");\n    \/\/fflush(stderr);\n  }\n  return(s);\n}\n\nstatic void server_bind(int s, struct addrinfo *res)\n{\n#ifdef DEBUG42\n  fprintf(stdout,\"bind()\\n\");\n#endif\n  if(bind(s, res-&gt;ai_addr, res-&gt;ai_addrlen) == -1) {\n    int errerrno = errno;\n    if(errerrno == 98) {\n      fprintf(stdout,\"%s cannot bind, waiting to bind\", procname);\n      while(errerrno == 98) {\n\tsleep(10);\n\tfprintf(stdout,\".\");\n\tfflush(stdout);\n\tbind(s, res-&gt;ai_addr, res-&gt;ai_addrlen);\n\terrerrno = errno;\n      }\n      fprintf(stdout,\"bind done!\\n\");\n      \/\/fflush(stdout);\n    } else {\n      int errerrno = errno;\n      fprintf(stderr,\"\\n%s: cannot bind()\", procname);\n      fprintf(stderr,\", errno: %d\", errerrno);\n      fprintf(stderr, \"(%s)\", strerror(errerrno));\n      fprintf(stderr,\"\\n\");\n      perror(\"bind\");\n      \/\/fflush(stderr);\n    }\n  }\n}\n\nstatic int server_listen(int s)\n{\n  int retval;\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"listen()\\n\");\n#endif\n  if((retval = listen(s,backlog)) == -1) { \/\/ ==!\n    int errerrno = errno;\n    fprintf(stderr,\"\\n%s: cannot listen()\", procname);\n    fprintf(stderr,\", errno %d\", errerrno);\n    fprintf(stderr, \"(%s)\", strerror(errerrno));\n    fprintf(stderr,\"\\n\");\n    perror(\"listen\");\n    \/\/fflush(stderr);\n  }\n  \n  return(retval);\n}\n\nstatic void server_close(int s)\n{\n#ifdef DEBUG42\n  fprintf(stdout,\"close(s)\\n\");\n#endif\n  if(close(s) == -1) {\n    int errerrno=errno;\n    fprintf(stderr,\"\\n%s: cannot close()\", procname);\n    fprintf(stderr,\", errno %d\", errerrno);\n    fprintf(stderr, \"(%s)\", strerror(errerrno));\n    fprintf(stderr,\"\\n\");\n    perror(\"close\");\n    \/\/fflush(stderr);\n  }\n}\n\nstatic int server_basic_socket()\n{\n  int s;\n  struct addrinfo *res;\n\n  server_getaddrinfo(myport, &amp;res);\n  s = server_socket(res);\n  server_bind(s, res);\n  freeaddrinfo(res);\n  server_listen(s);\n\n  return(s);\n}\n\n#define TIMEFORMAT \"%Z%Y%m%d%H%M%S\"\n#define HTMLTIMEFORMAT \"%a, %d %b %Y %H:%M:%S %Z\"\n\n\/\/ statistics for the previous minutes\n\nunsigned long prevhtmlseconds=0, htmlseconds;\nunsigned int callstats&#91;15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\n\nstatic void dbs_time_vars()\n{\n  htmlseconds = dbs_getseconds();\n\n  strftime(htmltimeshort, sizeof(htmltimeshort), TIMEFORMAT,\n\t   localtime((time_t *)&amp;htmlseconds));\n  strftime(htmltime, sizeof(htmltime), HTMLTIMEFORMAT,\n\t   localtime((time_t *)&amp;htmlseconds));\n\n  int c, d;\n  \n  unsigned long prevminute = prevhtmlseconds \/ 60 * 60;\n  unsigned long minute = htmlseconds \/ 60 * 60;\n  unsigned long diff = (minute - prevminute) \/ 60;\n\n  \/\/ statistics for the previous 10 minutes\n  \n  if(diff != 0) {\n    for(c = 15, d = 15 - diff; d &gt;= 0; c--, d--) {\n      callstats&#91;c] = callstats&#91;d];\n    }\n    for(; c &gt;= 0; c--)\n      callstats&#91;c] = 0;\n  }\n  callstats&#91;0]++;\n\n  fprintf(stdout,\"previous minutes\");\n  fprintf(stdout,\" prevmin:%10lu\", prevminute);\n  fprintf(stdout,\" min:%10lu\", minute);\n  fprintf(stdout,\" diff:%2lu\", diff);\n  fprintf(stdout,\" stat:\");\n  htmlprevminutes&#91;0]='\\0';\n  for(c=0;c&lt;15;c++) {\n    fprintf(stdout,\" %d\", callstats&#91;c]);\n    unsigned char buffer&#91;10];\n    sprintf(buffer,\"%d\", callstats&#91;c]);\n    if(strlen(htmlprevminutes) + 1 + strlen(buffer) &lt; sizeof(htmlprevminutes)) {\n      if(strlen(htmlprevminutes) &gt; 0)\n\tstrcat(htmlprevminutes, \" \");\n      strcat(htmlprevminutes, buffer);\n    }\n  }\n  fprintf(stdout,\"\\n\");\n  \n  prevhtmlseconds = htmlseconds;\n}\n\nunsigned long long dbs_get_useconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec + 1000000 * tv.tv_sec);\n}\n\n#include &lt;sys\/socket.h&gt;\n\nstatic void dbs_server_vars(struct sockaddr_in sa_cli, int addr_size, char *name)\n{\n  strcpy(htmlip, inet_ntoa(sa_cli.sin_addr));\n  sprintf(htmlport,\"%d\", sa_cli.sin_port);\n  htmlsslcipher&#91;0] = '\\0';\n  htmlhostname&#91;0] = '\\0';\n  \n  log_printf(\"\\n%s, Connection(%s) from %x\", procname, name, sa_cli.sin_addr.s_addr); \n  log_printf(\", ip %s\", htmlip);\n  log_printf(\", port %s\", htmlport);\n  log_printf(\", at %s\", htmltime);\n  \n  char host&#91;NI_MAXHOST], serv&#91;NI_MAXSERV];\n  \n  host&#91;0] = '\\0';\n  serv&#91;0] = '\\0';\n  if(getnameinfo((struct sockaddr *)&amp;sa_cli, addr_size, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {\n    log_printf(\", numeric hostname:%s\", host);\n    log_printf(\", numeric service:%s\", serv);\n  } else {\n    log_printf(\", numeric hostname:????\");\n    log_printf(\", numeric service:????\");\n  }\n  host&#91;0] = '\\0';\n  serv&#91;0] = '\\0';\n  if(getnameinfo((struct sockaddr *)&amp;sa_cli, addr_size, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICSERV) == 0) {\n    log_printf(\", name hostname:%s\", host);\n    log_printf(\", service:%s\", serv);\n    strncpy(htmlhostname, host, sizeof(htmlhostname));\n  } else {\n    log_printf(\", name hostname:????\");\n    log_printf(\", service:????\");\n  }\n  log_printf(\"\\n\");\n\n}\n\n#define DEBUG61 2\n\nstatic void dbs_get_header(int *len, unsigned char **buf, unsigned char *text)\n{\n  int count;\n  unsigned char *p;\n\n  if(text == NULL)\n    text = \"\";\n#ifdef DEBUG61\n  fprintf(stdout,\"get_header(): text:%s(%ld)\\n\", text, strlen(text));\n  fflush(stdout);\n#endif\n  p = text;\n  count = 0;\n  while(*p != '\\0' &amp;&amp;\n\tstrncmp(p,\"\\r\\n\\r\\n\",4) ) {\n    fprintf(stdout,\" %c\", *p);\n    fflush(stdout);\n    p++;\n    count++;\n  }\n  if(!strncmp(p,\"\\r\\n\", 2))\n    count += 2; \/\/ include one cr-lf pair\n  count++; \/\/ and '\\0'\n  if(*len &lt; count) {\n    *len = count;\n    *buf = realloc(*buf,*len);\n  }\n  strncpy(*buf, text, count - 1);\n  *(*buf + count - 1) = '\\0';\n}\n\nstatic void dbs_get_payload(int *len, unsigned char **buf, unsigned char *text)\n{\n  int count;\n  unsigned char *p;\n\n  if(text == NULL)\n    text = \"\";\n\n#ifdef DEBUG61\n  fprintf(stdout,\"get_payload(), text:%s(%ld)\\n\", text, strlen(text));\n  fflush(stdout);\n#endif\n  \n  p = text;\n  count = 0;\n  while(*p != '\\0' &amp;&amp;\n\tstrncmp(p,\"\\r\\n\\r\\n\",4) ) {\n    fprintf(stdout,\" %c\",*p);\n    fflush(stdout);\n    p++;\n  }\n  if(!strncmp(p,\"\\r\\n\\r\\n\",4))\n    p+=4; \/\/ include one cr-lf pair\n\n  count = strlen(p) + 1;\n\n  if(*len &lt; count) {\n    *len = count;\n    *buf = realloc(*buf, *len);\n  }\n  strncpy(*buf, p, count);\n  *(*buf + count - 1) = '\\0';\n}\n\n#ifdef SENT_HTML_LOG\n\nstatic void dbs_get_payload2(int *len, unsigned char **buf, unsigned char *text)\n{\n  int count;\n  unsigned char *p;\n\n  if(text == NULL)\n    text = \"\";\n\n#ifdef DEBUG61\n  fprintf(stdout,\"get_payload(), text:%s(%ld)\\n\",text,strlen(text));\n  fflush(stdout);\n#endif\n  \n  p = text;\n  count = strlen(text) + 1;\n\n  if(*len &lt; count) {\n    *len = count;\n    *buf = realloc(*buf,*len);\n  }\n  strcpy(*buf, p);\n}\n\n#endif\n\n#define aSENT_HTML_LOG 2\n\nstatic void dbs_query_vars()\n{\n  dbs_get_header((int *)&amp;htmlrecvheaderlen, &amp;htmlrecvheader, htmlin);\n  dbs_get_payload((int *)&amp;htmlrecvpayloadlen, &amp;htmlrecvpayload, htmlin);\n  dbs_get_header((int *)&amp;htmlsentheaderlen, &amp;htmlsentheader, html_get_string(0));\n#ifdef SENT_HTML_LOG\n  dbs_get_payload2((int *)&amp;htmlsentpayloadlen, &amp;htmlsentpayload, html_get_string(HTML_BUFFERS-1));\n#endif\n}\n\n#define DEBUG38 2\n\nstatic void http_client(int news, struct sockaddr_in sa_cli, int addr_size, char *name)\n{\n  int clen = 0;\n  int reads = 0;\n  int first = 1;\n  int bytes, totalbytes = 0;\n  unsigned char buffer10&#91;10];\n\n  unsigned long long useconds;\n\n  useconds = dbs_get_useconds();\n  \n  htmlparams = NULL;\n  htmlin&#91;0] = '\\0';\n\n  dbs_server_vars(sa_cli, addr_size, name);\n\n  while(htmlparams == NULL ||\n\tclen-strlen(htmlparams) &gt; 0) {\n    if(!first) {\n      log_printf(\", \");\n    }\n\n    struct pollfd fds;\n    fds.fd = news;\n    fds.events = POLLIN;\n    bytes = 0;\n    int retval = poll(&amp;fds,1,1024*1024);\n    log_printf(\"******poll: %d\\n\",retval);\n    if(retval &gt; 0) { \/\/ -1 err, 0 expire\n#ifdef DEBUG42\n      fprintf(stdout,\"read()\\n\");\n#endif\n      if((bytes = read(news, htmlin + totalbytes, htmlinlen - totalbytes)) &lt; 0) {\n\tfprintf(stderr,\"\\n%s: cannot read()\\n\", procname);\n\tperror(\"read\");\n\t\/\/fflush(stderr);\n      }\n      if(retval &gt; 0)\n\treads++;\n    } \n\n    log_printf(\"(%d bytes)\", bytes);\n    if(bytes == 0)\n      break;\n    if(bytes &gt; 3 &amp;&amp;\n       !isprint(htmlin&#91;0]) &amp;&amp;\n       !isprint(htmlin&#91;1]) &amp;&amp;\n       !isprint(htmlin&#91;2])) {\n      log_printf(\"https packet?\\n\");\n      htmlin&#91;0] = '\\0';\n      totalbytes = 0;\n      bytes = 0;\n      break;\n    }\n    *(htmlin + totalbytes + bytes) = '\\0';\n\n    totalbytes += bytes;\n    if(totalbytes &gt;= htmlinlen) {\n      \/\/ plus space for '\\0'\n      htmlin=realloc(htmlin, htmlinlen*2+1);\n      htmlinlen *= 2;\n    }\n    \n    htmlparams = dbs_html_get_params();\n    unsigned char *p = htmlin;\n    dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&amp;p);\n    if(!strcmp(htmlmethod, \"GET\"))\n      break;\n    dbs_html_get_request_line_num(\"Content-Length\", sizeof(buffer10), buffer10);\n    clen = atoi(buffer10);\n    first = 0;\n  }\n\n  if(totalbytes != 0) {\n    \n    log_printf(\"\\n%d reads\", reads);\n    log_printf(\", received %d chars\", totalbytes);\n    log_printf(\", read %d total bytes\", totalbytes);\n    log_printf(\", input buffer size %d chars\", htmlinlen);\n    log_printf(\", data=\\\"\");\n    log_dump_string(htmlin);\n    log_printf(\"\\\"\\n\");\n    \n    dbs_run_loop();\n    \n    log_printf(\"buffers(html):\");\n    for(int c = 0; c &lt; HTML_BUFFERS; c++) { \n      log_printf(\" %d:%ld\", c, strlen(html_get_string(c)));\n      if(strlen(html_get_string(c)) &gt; 0) {\n\tif((bytes = write(news, html_get_string(c), strlen(html_get_string(c)))) == -1) {\n\t  fprintf(stderr,\"\\n%s: cannot write() dbs_html&#91;%d]\\n\", procname, c);\n\t  perror(\"write\");\n\t  \/\/fflush(stderr);\n\t}\n      }\n    }\n    log_printf(\"\\n\");\n  }\n  dbs_query_vars();\n  useconds = dbs_get_useconds() - useconds;\n  sprintf(htmluseconds,\"%lld\", useconds);\n}\n\nint beepaccept=1;\n\n#define DEBUG45 2\n#define DEBUG57 2\n\nstatic void http_server()\n{\n  int quit, reset, addr_size;\n\n  struct sockaddr_in sa_cli;\n\n  signal(SIGPIPE, SIG_IGN);\n  signal(SIGCHLD, SIG_IGN);\n\n  dbs_open_semaphores();\n  \n  \/\/ plus space for '\\0'\n  htmlin = malloc(htmlinlen+1);\n  \n  reset = 1;\n  quit = 0;\n  \n  for(;;) {\n\n    if(quit) {\n      break;\n    }\n\n    if(reset) {\n      s = server_basic_socket();\n      reset = 0;\n    }\n  \n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n    \n    addr_size = sizeof(sa_cli);\n#ifdef DEBUG42\n    fprintf(stdout,\"accept()\\n\");\n#endif\n    if((news = accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size)) == -1) {\n      fprintf(stderr,\"\\n%s: cannot accept()\\n\", procname);\n      perror(\"accept\");\n      \/\/fflush(stderr);\n    }\n\n    dbs_time_vars();\n    \n    if(beepaccept) {\n      fprintf(stderr,\"\\a\");\n      fflush(stderr);\n    }\n    \n    pid_t pid;\n#ifdef DEBUG45\n    fprintf(stdout,\"Fork start (parent)\");\n    fprintf(stdout,\" getpid:%d getppid:%d\", getpid(), getppid());\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n#ifdef DEBUG42\n    fprintf(stdout,\"fork()\\n\");\n#endif\n    if((pid = fork()) &lt; 0) {\n      dbs_close_semaphores();\n\n      fprintf(stderr,\"\\n%s: cannot fork()\", procname);\n      fprintf(stderr,\", errno %d\", errno);\n      fprintf(stderr, \"(%s)\", strerror(errno));\n      fprintf(stderr, \"\\n\");\n      perror(\"close\");\n      \/\/fflush(stderr);\n      exit(1);\n    } else if(pid == 0) { \/\/ child\n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n#endif\n      log_clear();\n\n#ifdef DEBUG42\n      fprintf(stdout,\"log_printf()\\n\");\n#endif\n      log_printf(\"==========\\n\");\n\n#ifdef DEBUG45\n      fprintf(stdout,\"Fork start (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      close(s);\n\n#ifdef DEBUG42\n      fprintf(stdout,\"http_client()\\n\");\n#endif\n      http_client(news, sa_cli, addr_size, \"http\");\n\n#ifdef DEBUG57\n      fprintf(stdout,\"%s\", logbuf);\n      fflush(stdout);\n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n#endif\n      log_clear();\n#endif\n\n      dbs_run_critical_sections(); \n     \n#ifdef DEBUG42\n      fprintf(stdout,\"server_close(news)\\n\");\n#endif\n      server_close(news);\n\n      fprintf(stdout,\"%s\", logbuf);\n      fflush(stdout);\n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n#endif\n      log_clear();\n      \n#ifdef DEBUG45\n      fprintf(stdout,\"Fork end (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      exit(0);\n    }\n#ifdef DEBUG45\n    fprintf(stdout,\"Fork end (parent)\");\n    fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n#ifdef DEBUG42\n      fprintf(stdout,\"server_close(news)\\n\");\n#endif\n    server_close(news);\n  } \/\/ for(;;)\n  dbs_close_semaphores();\n}\n\nstatic void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)\n{\n  int status, ok;\n  unsigned char buffer10&#91;10];\n\n  SSL *ssl;\n  X509 *peer_cert;\n\n  unsigned long long useconds;\n\n  useconds = dbs_get_useconds();\n  \n  ok = 1;\n\n  dbs_server_vars(sa_cli, addr_size, name);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_new()\\n\");\n#endif\n  if((ssl = SSL_new(ctx)) == NULL) {\n    fprintf(stdout,\"\\n%s: cannot SSL_new()\", procname);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_set_fd()\\n\");\n#endif\n  if(SSL_set_fd(ssl,news) != 1) {\n    fprintf(stdout,\"\\n%s: cannot SSL_set_fd()\\n\", procname);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_accept()\\n\");\n#endif\n  if((status = SSL_accept(ssl)) &lt; 0) {\n    fprintf(stdout,\"\\n%s: cannot SSL_accept(), retval: %d\\n\", procname,status);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_get_peer_certificate()\\n\");\n#endif\n  peer_cert = SSL_get_peer_certificate(ssl);\n  if(peer_cert == NULL) {\n    log_printf(\", No peer certificate\");\n  }\n  \n  log_printf(\"\\n\");\n  \n  int clen = 0;\n  int reads = 0;\n  int first = 1;\n  int bytes, totalbytes = 0;\n\n  htmlparams = NULL;\n\n  htmlin&#91;0] = '\\0';\n  while(htmlparams == NULL || clen-strlen(htmlparams) &gt; 0) {\n    if(!first) {\n      log_printf(\", \");\n    } \n    int tries = 0;\n    for(;;) {\n      bytes = SSL_read(ssl, htmlin+totalbytes, htmlinlen-totalbytes);\n\n      int errerrno, err, err2;\n\n      errerrno = errno;\n      err = SSL_get_error(ssl, bytes);\n      err2 = ERR_get_error();\n\n      log_printf(\"\\nSSL_read()\");\n      log_printf(\", retval %d\", bytes);\n      log_printf(\", errno: %d\", errerrno);\n      log_printf(\", SSL_get_error(): %d\", err);\n      log_printf(\", ERR_get_error(): %d\", err2);\n\n      \n      while((err2 = ERR_get_error()) != 0)\n\tlog_printf(\", %d\",err2);\n      if(bytes &gt;= 0) {\n\treads++;\n\tbreak;\n      }\n      if(bytes &lt; 0) {\n\tif(++tries &lt; 5 &amp;&amp; (err == 1 || err == 5)) {\n\t  usleep(1024 * 512 \/ 5);\n\t  log_printf(\" try:%d\", tries);\n\t  continue;\n\t}\n\tlog_printf(\"cannot SSL_read()\\n\");\n\tok = 0;\n\tbreak;\n      } \/\/ if(bytes\n      break;\n    } \/\/ for(;;)\n    log_printf(\"(%d bytes)\", bytes);\n    if(!ok)\n      break;\n\n    *(htmlin + totalbytes + bytes) = '\\0';\n    if(bytes == 0)\n      break;\n\n    totalbytes += bytes;\n    if(totalbytes &gt;= htmlinlen) {\n      \/\/ plus space for '\\0'\n      htmlin=realloc(htmlin, htmlinlen * 2 + 1);\n      htmlinlen *= 2;\n    }\n    \n    htmlparams = dbs_html_get_params();\n    unsigned char *p=htmlin;\n    dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&amp;p);\n    if(!strcmp(htmlmethod,\"GET\"))\n      break;\n    dbs_html_get_request_line_num(\"Content-Length\",\n\t\t\t\t  sizeof(buffer10), buffer10);\n    clen = atoi(buffer10);\n    first = 0;\n  }\n\n  log_printf(\"\\n%d reads\", reads);\n  log_printf(\", received %d chars\", totalbytes);\n  log_printf(\", read %d total bytes\", totalbytes);\n  log_printf(\", input buffer size %d chars\", htmlinlen);\n  log_printf(\", data=\\\"\");\n  log_dump_string(htmlin);\n  log_printf(\"\\\"\\n\");\n  \n  strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));\n  \n  if(ok) \n    dbs_run_loop();\n  \n  if(ok) {\n    log_printf(\"buffers(ssl):\");\n    for(int c = 0; c &lt; HTML_BUFFERS; c++) {\n      log_printf(\" %d:%ld\", c, strlen(html_get_string(c)));\n      if(strlen(html_get_string(c)) &gt; 0) {\n#ifdef DEBUG42\n\tfprintf(stdout,\"SSL_write()\\n\");\n#endif\n\tif((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) &lt; 1) {\n\t  fprintf(stdout,\"\\n%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\",\n\t\t  procname, c, status, SSL_get_error(ssl, status));\n\t}\n      }\n    }\n  }\n  log_printf(\"\\n\");\n  log_printf(\"\\nSSL connection using %s\", htmlsslcipher);\n  log_printf(\"\\n\");\n\n#ifdef DEBUG42\n  fprintf(stdout,\"dbs_query_vars()\\n\");\n#endif\n  dbs_query_vars();\n  useconds = dbs_get_useconds() - useconds;\n  sprintf(htmluseconds,\"%lld\", useconds);\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_free()\\n\");\n#endif\n  SSL_free(ssl);\n}\n\nstatic SSL_CTX *server_https_init()\n{\n  SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_library_init()\\n\");\n#endif\n  SSL_library_init();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_add_ssl_algorithms()\\n\");\n#endif\n  OpenSSL_add_ssl_algorithms();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_add_ciphers()\\n\");\n#endif\n  OpenSSL_add_all_ciphers();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"OpenSSL_load_error_strings()\\n\");\n#endif\n  SSL_load_error_strings();\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSLv23_server_method()\\n\");\n#endif\n  if((method = (SSL_METHOD *)    \n      SSLv23_server_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\\n\", procname);\n    \/\/fflush(stderr);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_new()\\n\");\n#endif\n  if((ctx=SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\\n\", procname);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_use_certificate_file()\\n\");\n#endif\n  if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) != 1) {\n    int err2;\n    err2=ERR_get_error();\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate_file()\", procname);\n    fprintf(stderr,\", ERR_get_error(): %d\", err2);\n    while((err2 = ERR_get_error()) != 0)\n      fprintf(stderr,\", %d\", err2);\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_use_PrivateKey_file()\\n\");\n#endif\n  if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM) != 1) {\n    int err2;\n    err2=ERR_get_error();\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_PrivateKey_file()\", procname);\n    fprintf(stderr,\", ERR_get_error(): %d\", err2);\n    while((err2 = ERR_get_error()) != 0)\n      fprintf(stderr,\", %d\", err2);\n    fprintf(stderr,\"\\n\");\n    fflush(stderr);\n  }\n  \n#ifdef DEBUG42\n  fprintf(stdout,\"SSL_CTX_load_verify_locations()\\n\");\n#endif\n  if(SSL_CTX_load_verify_locations(ctx, cert_file, NULL) != 1) {\n    int err2;\n    err2 = ERR_get_error();\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_load_verify_locations()\", procname);\n    fprintf(stderr,\", ERR_get_error(): %d\", err2);\n    while((err2 = ERR_get_error()) != 0)\n      fprintf(stderr,\", %d\", err2);\n  }\n  return(ctx);\n}\n\n#define DEBUG59 2\n#define DEBUG81 2\n\nstatic void https_server()\n{\n  int quit, reset, addr_size;\n  \n  \/\/SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n\n  struct sockaddr_in sa_cli;\n\n  signal(SIGPIPE, SIG_IGN);\n  signal(SIGCHLD, SIG_IGN);\n\n  \/\/ plus space for '\\0'  \n  htmlin = malloc(htmlinlen+1);\n\n  reset = 1;\n  quit = 0;\n  \n  for(;;) {\n\n    if(quit) {\n      if(ctx != NULL)\n\tSSL_CTX_free(ctx);\n      break;\n    }\n\n    if(reset) {\n      if(ctx != NULL) {\n#ifdef DEBUG42\n\tfprintf(stdout,\"SSL_CTX_free()\\n\");\n#endif\n\tSSL_CTX_free(ctx);  \n      }\n\n      ctx = server_https_init();\n      s = server_basic_socket();\n\n      dbs_open_semaphores();\n      reset = 0;\n    } \/\/ if(reset)\n\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n    \n    addr_size = sizeof(sa_cli);\n#ifdef DEBUG42\n    fprintf(stdout,\"accept()\\n\");\n#endif\n    if((news = accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size)) == -1) {\n      fprintf(stderr,\"\\n%s: cannot accept()\\n\", procname);\n      perror(\"accept\");\n    }\n\n    dbs_time_vars();\n    \n    if(beepaccept) {\n      fprintf(stderr,\"\\a\");\n      fflush(stderr);\n    }\n\n    pid_t pid;\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork start (parent)\");\n    fprintf(stdout,\" getpid:%d getppid:%d\", getpid(), getppid()); \n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n#ifdef DEBUG42\n    fprintf(stdout,\"fork()\\n\");\n#endif\n\n    if((pid = fork()) &lt; 0) {\n      dbs_close_semaphores();\n      \n      fprintf(stderr,\"\\n%s: cannot fork()\", procname);\n      fprintf(stderr,\", errno %d\", errno);\n      fprintf(stderr, \"(%s)\", strerror(errno));\n      fprintf(stderr,\"\\n\");\n      perror(\"fork\");\n      exit(1);\n\n    } else if(pid == 0) {\n\n#ifdef DEBUG42\n      fprintf(stdout,\"close(s)\\n\");\n      fflush(stdout);\n#endif\n      close(s);\n      \n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n      fflush(stdout);\n#endif\n      log_clear();\n\n#ifdef DEBUG42\n      fprintf(stdout,\"log_printf()\\n\");\n      fflush(stdout);\n#endif\n      fprintf(stdout,\"log\");\n      fflush(stdout);\n      log_printf(\"==========\\n\");\n      fprintf(stdout,\" done\");\n      fflush(stdout);\n      \n#ifdef DEBUG59\n      fprintf(stdout,\"Fork start (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n\n#ifdef DEBUG42\n      fprintf(stdout,\"https_client()\\n\");\n      fflush(stdout);\n#endif\n      https_client(news, ctx, sa_cli, addr_size, \"https\");\n      \n#ifdef DEBUG81\n      fprintf(stdout,\"%s\",logbuf);\n      fflush(stdout);\n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n      fflush(stdout);\n#endif\n      log_clear();\n#endif\n\n      dbs_run_critical_sections();\n      \n#endif\n      \n#ifdef DEBUG42\n      fprintf(stdout,\"server_close(news)\\n\");\n      fflush(stdout);\n#endif\n      server_close(news);\n\n      fprintf(stdout,\"%s\", logbuf);\n      fflush(stdout);\n#ifdef DEBUG42\n      fprintf(stdout,\"log_clear()\\n\");\n      fflush(stdout);\n#endif\n      log_clear();\n      \n#ifdef DEBUG59\n      fprintf(stdout,\"Fork end (child)\");\n      fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n      fprintf(stdout,\"\\n\");\n      fflush(stdout);\n#endif\n      exit(0);\n    } \/\/ if(pid == 0)\n#ifdef DEBUG42\n    fprintf(stdout,\"server_close(news)\\n\");\n    fflush(stdout);\n#endif\n    server_close(news);\n\n#ifdef DEBUG59\n    fprintf(stdout,\"Fork end (parent)\");\n    fprintf(stdout,\" pid:%d getpid:%d getppid:%d\", pid, getpid(), getppid());\n    fprintf(stdout,\"\\n\");\n    fflush(stdout);\n#endif\n  } \/\/ for(;;)\n  SSL_CTX_free(ctx);  \n\n  dbs_close_semaphores();\n}\n\nstatic unsigned char *dbs_save_string(unsigned char *string)\n{\n  unsigned char *temp = malloc(strlen(string) + 1);\n  strcpy(temp, string);\n  return(temp);\n}\n\nstatic void dbs_file_digest(char *filename, unsigned char *hash)\n{\n  int c;\n  unsigned char buffer&#91;1024];\n  FILE *fp1;\n  HashCtx ctx;\n  \n  HashInit(&amp;ctx);\n  if((fp1 = fopen(filename, \"rb\")) != NULL) {\n    while((c = fread(buffer, 1, sizeof(buffer), fp1)) &gt; 0)\n      HashUpdate(&amp;ctx, buffer, c);\n    fclose(fp1);\n  }\n  HashFinal(hash, &amp;ctx);  \n}\n\nint dba_main(int argc,char *argv&#91;]);\n\nstatic void dbs_version()\n{\n  fprintf(stdout,\"%s, \", programname);\n  fprintf(stdout,\"%s\\n\", copyright);\n  fflush(stdout);\n}\n\nint https=1;\n\nint dbs_main(int argc,char *argv&#91;])\n{\n  int c;\n  for(c = 1; c &lt; argc; c++) {\n    if(!strncmp(argv&#91;c], \"--https\", 7))\n      https = 1;\n    else if(!strncmp(argv&#91;c], \"--http\", 6))\n      https = 0;\n    else if(!strncmp(argv&#91;c], \"--port\", 6)) {\n      if(argv&#91;c]&#91;6] != '\\0')\n        myport = dbs_save_string(&amp;argv&#91;c]&#91;6]);\n      else\n        myport = dbs_save_string(argv&#91;++c]);\n    } else if(!strncmp(argv&#91;c], \"-p\", 2)) {\n      if(argv&#91;c]&#91;2] != '\\0')\n        myport = dbs_save_string(&amp;argv&#91;c]&#91;2]);\n      else\n        myport = dbs_save_string(argv&#91;++c]);\n    } else if(!strncmp(argv&#91;c], \"--version\", 9)) {\n      dbs_version();\n    } else if(!strncmp(argv&#91;c], \"-v\", 2)) {\n      dbs_version();\n    }\n  }\n  return(0);\n}\n\nint main(int argc,char *argv&#91;])\n{\n  unsigned char filedigest&#91;HashLen];\n  \n  procname = argv&#91;0];\n\n  dbs_file_digest(\"\/proc\/self\/exe\", filedigest);\n  htmldigest&#91;0] = '\\0';\n  for(int c = 0; c &lt; HashLen; c++) {\n    char twodigits&#91;3];\n    sprintf(twodigits,\"%02x\", filedigest&#91;c]);\n    strcat(htmldigest, twodigits);\n  }\n\n  filenamehead&#91;0] = '\\0';\n  \n  dbs_main(argc,argv);\n  dba_main(argc,argv);\n  \/\/db2_main(argc,argv);\n\n  fprintf(stdout,\"%s\", programname);\n  fflush(stdout);\n  if(https)\n    fprintf(stdout,\", https\");\n  else\n    fprintf(stdout,\", http\");\n\n  fprintf(stdout,\", port %s\", myport);\n\n  fprintf(stdout,\",  sha256(%s)\\n\", htmldigest);\n  fflush(stdout);\n\n  FILE *fp1;\n  unsigned char filename&#91;64];\n    \n  snprintf(filename, sizeof(filename), \"%spid.deb\", filenamehead);\n  if((fp1 = fopen(filename,\"w\")) != NULL) {\n    fprintf(fp1,\"%d\\n\", getpid());\n    fclose(fp1);\n  }\n\n#define aDEBUG_FORT\n  \n#ifdef DEBUG_FORT\n  unsigned char buffer64&#91;64];\n  fprintf(stdout,\"dbs: for(;;)\\n\");\n  fflush(stdout);\n  for(;;) {\n    fort_random_data(sizeof(buffer64),buffer64);\n  }\n#endif\n  \n  if(https)\n    https_server();\n  else\n    http_server();\n\n  exit(0);\n}<\/code><\/pre>\n\n\n\n<p>newressu.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ressu_genbytes(int size, unsigned char *buffer);\nunsigned long ressu_gen_limit(unsigned long limit);\n\n#define INPUT_RESSU 0\n#define INPUT_DEBUG 1\n#define INPUT_FAST 2\n#define INPUT_SINGLE 3\n#define INPUT_FORT 6\n#define INPUT_FORTXOR 7\n#define INPUT_URANDOM 8\n#define INPUT_RANDOM 9\n\nextern int input;\nextern int newressu_output;\nextern char *randomgen&#91;];<\/code><\/pre>\n\n\n\n<p>fort.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Perustuu Bruce Schneierin kirjassa esitt\u00e4m\u00e4\u00e4n fortuna j\u00e4rjestelm\u00e4\u00e4n.\n * Written by Jari Kuivaniemi\n *\/\n\n#ifndef SHA256_H\n#include \"sha256.h\"\n#endif\n\n#define aFORT_USE_RDRAND 2\n#define aFORT_USE_RDSEED 2\n\ntypedef unsigned long long IUTIME;\n\nextern int fort_verbose;\nextern int fort_partial_line;\nextern int fort_use_web;\n\nextern unsigned char fort_random_file&#91;128];\nextern unsigned char fort_pools_file&#91;128];\n#ifdef DEBUG10\nstatic char fort_events_file&#91;128] = \"fortevents.deb\";\n#endif\nunsigned char cvar&#91;16];\nint cvarsize;\n\nvoid inccvar();\nvoid clearcvar();\nvoid hash_update_cvar(HashCtx *hash);\n\nvoid fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf);\nvoid fort_add_random_event_timer_start(IUTIME *micros);\nvoid fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *millis);\nvoid fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf,int size);\nvoid fort_add_random_event_time(int *pool, int source, int mode);\nvoid fort_rekey(unsigned char *buf);\nvoid fort_pseudo_random_data(int len,unsigned char *buf);\nvoid fort_pseudo_random_data_xor(int len,unsigned char *buf);\nvoid fort_reseed(int len,unsigned char *buf);\nvoid fort_random_data(int len,unsigned char *buf);\nvoid fort_random_data_xor(int len,unsigned char *buf);\nint fort_random_data_byte();\nvoid fort_clear();\nint fort_random_data_byte_limit(int limit);\nvoid fort_random_data_buffer(int size, unsigned char *buffer);\nvoid fort_save();\nvoid fort_read_file();\nvoid fort_mix();\nvoid fort_init();\nvoid hash_init(HashCtx *hash);\nvoid hash_update(HashCtx *hash, unsigned char *data, int len);\nvoid hash_final(unsigned char digest&#91;HashLen], HashCtx *hash);\n\nvoid fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);\nvoid fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);\n\nvoid fort_hash_command(unsigned char *command, unsigned char *hash);\n\nint rdrand_bytes(int buflen, unsigned char *buf);\nint rdseed_bytes(int buflen, unsigned char *buf);\n\n#ifdef FORT_INTERNAL_EVENTS\n#define FORT_INTERNAL_EVENTS_START(source) \\\n  IUTIME micros;                           \\\n  static int \\\n    pool=0, pool2=0; \\\n  if(fort_internal_events) { \\\n    fort_add_random_event_time(&amp;pool, \\\n    source, fort_internal_event_mode); \\\n    fort_add_random_event_timer_start(&amp;micros); \\\n  }\n#else\n#define FORT_INTERNAL_EVENTS_START(source)\n#endif\n\n#ifdef FORT_INTERNAL_EVENTS\n#define FORT_INTERNAL_EVENTS_END(source) \\\n  if(fort_internal_events) \\\n    fort_add_random_event_timer_do(&amp;pool2, \\\n      source, fort_internal_event_mode, \\\n      &amp;micros);\n#else\n#define FORT_INTERNAL_EVENTS_END(source)\n#endif\n\n#ifdef FORT_EVENTS\n#define FORT_EVENTS_START(source) \\\n  IUTIME micros;                           \\\n  static int \\\n    pool=0, pool2=0; \\\n  if(fort_events) { \\\n    fort_add_random_event_time(&amp;pool, \\\n    source, fort_event_mode); \\\n    fort_add_random_event_timer_start(&amp;micros); \\\n  }\n#else\n#define FORT_EVENTS_START(source)\n#endif\n\n#ifdef FORT_EVENTS\n#define FORT_EVENTS_END(source) \\\n  if(fort_events) \\\n    fort_add_random_event_timer_do(&amp;pool2, \\\n      source, fort_event_mode, \\\n      &amp;micros);\n#else\n#define FORT_EVENTS_END(source)\n#endif<\/code><\/pre>\n\n\n\n<p>sha256.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifndef SHA256_H\n#define SHA256_H\n\n#define HashName   \"SHA256\"\n#define HashInit   SHA256Init\n#define HashUpdate SHA256Update\n#define HashFinal  SHA256Final\n#define HashLen    32\n#define HashCtx    SHA256_CONTEXT\n\ntypedef unsigned char IUBYTE;\ntypedef unsigned int IUWORD;\ntypedef unsigned long long IULONG;\n\ntypedef struct {\n    IUWORD state&#91;8];\n    IULONG count;\n    IUBYTE buffer&#91;64];\n} SHA256_CONTEXT;\n\nvoid SHA256Init(SHA256_CONTEXT *sha256);\nvoid SHA256Update(SHA256_CONTEXT* sha256, unsigned char *data, int len);\nvoid SHA256Final(unsigned char digest&#91;32], SHA256_CONTEXT *sha256);\n\nvoid sha_test();\n\n#endif<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>dbs.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define aRESSU 2\n#define aFORT 2\n\n#define HTML_LAST_BUFFER 4\n\nint dbs_get_parameter(char *name, int valuelen, unsigned char *value);\nvoid dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value);\nint dbs_html_get_string(unsigned char *string,unsigned char **str,int len);\nint dbs_parse_html_parameter(int namelen, unsigned char *name, int valuelen,unsigned char *value, unsigned char **s);\n\nvoid log_clear();\nvoid log_free();\nvoid log_printf(const char *format, ...);\n\n\/*\nint dbs_parse_hex1(unsigned char **str);\nint dbs_parse_html_string(int stringlen, unsigned char *string, unsigned char **html);\nunsigned long dbs_getseconds();\nunsigned char *dbs_html_get_request_line(unsigned char *name);\nvoid dbs_html_get_request_line_num(unsigned char *name, int lenbuffer, unsigned char *buffer);\nvoid dbs_html_parse_string(int buflen, char *buf, unsigned char **p2);\nvoid dbs_html_parse_filename(int buflen, char *buf, unsigned char *p);\nunsigned char *dbs_html_get_params();\nvoid dbs_version();\n*\/<\/code><\/pre>\n\n\n\n<p>html.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *html&#91;9];\n\nvoid html_set(int html);\nint html_get();\nunsigned char *html_get_string(int bufno);\nvoid html_clear();\nvoid html_clear_all();\nvoid html_printf(const char *format, ...);\nvoid html_buf_printf(int bufno, const char *format, ...);\nvoid html_start();\nvoid html_indent(unsigned char *p);\n\n#define dbs_html_set html_set\n#define dbs_html_get html_get\n#define dbs_html_clear html_clear\n#define dbs_html_printf_valist html_printf_valist\n#define dbs_html_printf html_printf\n#define dbs_html_buf_printf html_buf_printf\n\n#define HTML_BUFFERS 9<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n. Maailman parhaat satunnaisbitit: https:\/\/moijari.com:5006. \u00c4l\u00e4 kuitenkaan k\u00e4yt\u00e4 n\u00e4it\u00e4 sellaisenaan, summaa useampi generaattori, ja mielell\u00e4\u00e4n viimeinen omassa ohjelmassa. Edit korjailen raporttia l\u00e4hip\u00e4ivien ja viikkojen aikana. Sorsia en ole viel\u00e4 kokeillut k\u00e4\u00e4nt\u00e4\u00e4&#8230; Sain k\u00e4\u00e4nnetty\u00e4 sorsan. My\u00f6s html lokit kirjoitetaan useammassa osassa. Lis\u00e4tty palvelimiin vuorot lokien kirjoittamiseen. Raportti postin lopussa ennen sorsia. Korjattu pari bugia&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=1799\">Continue reading <span class=\"screen-reader-text\">DBS 0.12 Finally server stays up<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,5],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1799"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1799"}],"version-history":[{"count":52,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1799\/revisions"}],"predecessor-version":[{"id":1871,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1799\/revisions\/1871"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1799"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1799"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1799"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}