{"id":1522,"date":"2021-01-17T03:37:54","date_gmt":"2021-01-17T01:37:54","guid":{"rendered":"https:\/\/moijari.com\/?p=1522"},"modified":"2021-06-08T13:56:15","modified_gmt":"2021-06-08T11:56:15","slug":"dbs-versio-0-08","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=1522","title":{"rendered":"DBS versio 0.08"},"content":{"rendered":"\n<p>DBS on tertun palvelinohjelma, joka vastaanottaa asiakkaan selaimelta sivupyynt\u00f6j\u00e4, kutsuu sovellusohjelmaa (DBA), joka muotostaa sivupyynn\u00f6n pohjalta vastauksen. Vastaus palautetaan DBS:lle, joka l\u00e4hett\u00e4\u00e4 tuloksen asiakkaalle.<\/p>\n\n\n\n<p>Edit: muutoksia julkaisun j\u00e4lkeen:<\/p>\n\n\n\n<p>Palvelimissa on viel\u00e4 ongelmaa Safari-selaimen kanssa, safari menee &#8220;luuppiin&#8221;, jos haetaan sek\u00e4 portillista ja portitonta URL:\u00e4\u00e4 vuorotellen (moijari.com ja moijari.com:5005).<\/p>\n\n\n\n<p>.ico (favicon.ico) tiedostopyynt\u00f6jen ohittamista varten lis\u00e4tty muuttuja htmlextension muuttuja, sille hakurutiini dbs_html_parse_extension ja kutsu edelliselle rutiinille. Ei korjannut safari ongelmaa. Seuraavana ressu3 (moijari.com:5005) koodi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dba_loop()\n{\n  html_clear_all();\n  if(!strcmp(htmlextension,\"ico\")) {\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(\"\\n&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;\/head&gt;\");\n\n    dbs_html_printf(\"&lt;body&gt;\");\n\n    ressu3_app();\n\n    dbs_html_printf(\"&lt;br&gt;&lt;br&gt;%s,  sha256(%s)&lt;br&gt;&lt;br&gt;\", programname,\n                    htmldigest);\n    dbs_html_printf(\"\\t\\toriginal url: &lt;a href=\\\"https:\/\/moijari.com:5001\\\"&gt;https:\/\/moijari.com:5005&lt;\/a&gt;\\n\");\n    dbs_html_printf(\"\\t\\t or &lt;a href=\\\"https:\/\/moijari.com:5005\\\"&gt;https:\/\/moijari.com:5005&lt;\/a&gt;&lt;br&gt;\\n\");\n\n    dbs_html_printf(\"&lt;\/body&gt;\");\n\n    dbs_html_printf(\"&lt;\/html&gt;\");\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    dbs_html_printf(\"Content-Length: %d\", len);\n    dbs_html_printf(\"\\r\\n\\r\\n\");\n\n  }\n}<\/code><\/pre>\n\n\n\n<p>End of muutokset.<\/p>\n\n\n\n<p>Ohjelman k\u00e4ytt\u00e4mi\u00e4 muuttujia:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>unsigned char *htmlin;\nint htmlinlen=2048;\n\nunsigned char htmlmethod&#91;10];\nunsigned char htmlpath&#91;128];\nunsigned char htmlversion&#91;32];\nunsigned char htmlfilename&#91;64];\nunsigned char htmlextension&#91;10];\nunsigned char htmlsessionid&#91;33];\nunsigned char htmltime&#91;32];\nunsigned char htmltimeshort&#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;33];\nunsigned char htmlport&#91;10];\nunsigned char htmllanguage&#91;10];<\/code><\/pre>\n\n\n\n<p>Rutiini muuttaa html-scriptin hexana esitetyn yksi numeroisen luvun  int:iksi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static 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}<\/code><\/pre>\n\n\n\n<p>T\u00e4m\u00e4 rutiini muodostaa html parametrist\u00e4 UTF8-merkkinonon. <\/p>\n\n\n\n<p>T\u00e4ss\u00e4 versiossa on lis\u00e4tty satunnaisuuden ker\u00e4ysrutiineja fort:lle (FORT_EVENTS_START ja FORT_EVENT_END), kuten muissakin my\u00f6hemmiss\u00e4 rutiineissa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static int dbs_parse_html_string(\n    int stringlen, unsigned char *string,\n    unsigned char **html)\n{\n  int c,d,count,ok;\n  unsigned char *s=string;\n  unsigned char *h=*html;\n\n  FORT_EVENTS_START(300)\n\n  ok=0;\n  count=0;\n\n  while(isalnum(*h)||*h=='%'||*h=='+'||*h=='-'||*h=='_' || *h=='.'|| *h==',' || *h=='*') {\n    ok=1;\n    if(*h=='%') {\n      h++;\n      if((c=dbs_parse_hex1(&amp;h))&gt;=0) {\n        if((d=dbs_parse_hex1(&amp;h))&gt;=0) {\n          c=c*16+d;\n        } else\n          c=c;\n      } else\n        c=64;\n      if(++count&lt;stringlen)\n        *s++=c;\n    } else if(*h=='+') {\n      if(++count&lt;stringlen)\n        *s++=' ';\n      h++;\n    } else {\n      if(++count&lt;stringlen)\n        *s++=*h;\n      h++;\n    }\n  }\n  *s='\\0';\n  *html=h;\n\n  FORT_EVENTS_END(301)\n\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavassa rutiinit, joita k\u00e4ytet\u00e4\u00e4n satunnaisuuden ker\u00e4\u00e4miseen edellisess\u00e4 ja seuraavissa funktioissa. Olen lis\u00e4nnyt sen sellaisiin rutiineihin jotka sis\u00e4lt\u00e4v\u00e4t suorituspituutensa puolesta suoritusajan vaihtelua. Jos et halua k\u00e4ytt\u00e4\u00e4 n\u00e4it\u00e4 lis\u00e4\u00e4 pikku-a FORT_EVENTS m\u00e4\u00e4ritykseen. Voit tarkastella tapahtumien satunnaisuutta &#8220;grep source=300 fortevents.deb&#8221; komennolla, jossa 300 on halutun l\u00e4hteen numero.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#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>dbs_html_get_string muuntaa koko merkkijonon, ei pelk\u00e4st\u00e4\u00e4n parametrej\u00e4 UTF8 muotoon(se sis\u00e4lt\u00e4\u00e4 my\u00f6s parametrierottimen &#8216;&amp;&#8217;).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#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  FORT_EVENTS_START(302)\n\n  n=string;\n  p=*str;\n  ok=0;\n\n  count=0;\n  while(isalnum(*p)||*p=='%'||*p=='+'||\n      *p=='-'||*p=='_'||*p=='=' || *p=='&amp;' || \n      *p=='.' || *p=='*') {\n    ok=1;\n    if(*p=='%') {\n      p++;\n      if((c=dbs_parse_hex1(&amp;p))&gt;=0) {\n        if((d=dbs_parse_hex1(&amp;p))&gt;=0) {\n          c=c*16+d;\n        } else\n          c=c;\n      } else\n        c=64;\n      if(count++&lt;len)\n        *n++=c;\n    } else if(*p=='+') {\n      if(count++&lt;len)\n        *n++=' ';\n      p++;\n    } else {\n      if(count++&lt;len)\n        *n++=*p++;\n      else\n        p++;\n    }\n  }\n  *n='\\0';\n  *str=p;\n\n  FORT_EVENTS_END(303)\n\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini palauttaa seuraavan parametrin nimen ja arvon. Merkkijonon parsiminen aloitetaan s osoitteesta ja suorituksen j\u00e4lkeen uusi merkkijonon kohta talletetaan takaisin s muuttujaan (**):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int dbs_parse_html_parameter(int namelen, unsigned char *name, \n    int valuelen,unsigned char *value,\n    unsigned char **s)\n{\n  FORT_EVENTS_START(304)\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  FORT_EVENTS_END(305)\n\n  return(1);\n}<\/code><\/pre>\n\n\n\n<p>Seuraava rutiini palauttaa halutun nimisen parametrin html sivun parametreista: Parametrit alkavat kohdasta htmlparams.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int 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  FORT_EVENTS_START(306)\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  FORT_EVENTS_END(307)\n\n  return(ok);\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 vanha tuttu sekuntien haku:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned long dbs_getseconds()\n{\n  struct timeval tv;\n\n  gettimeofday(&amp;tv, NULL);\n\n  return((IUTIME)tv.tv_sec);\n}<\/code><\/pre>\n\n\n\n<p>Seuraavalla rutiinilla palautetaan html-otsakkeen rivi, joka alkaa tietyll\u00e4 merkkijonolla: (t\u00e4ll\u00e4 haetaan ainakin Cookie ja Content-Length -rivit: (sessionid kentt\u00e4\u00e4 (+ ip:t\u00e4) ei viel\u00e4 tarkasteta, ip:t poistettu, sessionid poistettu)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EET20201211183424, ip=\"x.x.x.x\", callid=\"1826\"\nPOST \/app HTTP\/1.1^M\nHost: x.x.x.x:5004^M\nUser-Agent: Mozilla\/5.0 (X11; Ubuntu; Linux x86_64; rv:83.0) Gecko\/20100101 Firefox\/83.0^M\nAccept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,*\/*;q=0.8^M\nAccept-Language: en-US,en;q=0.5^M\nAccept-Encoding: gzip, deflate, br^M\nContent-Type: application\/x-www-form-urlencoded^M\nContent-Length: 230^M\nOrigin: https:\/\/x.x.x.x:5004^M\nConnection: keep-alive^M\nReferer: https:\/\/x.x.x.x:5004\/logon^M\nCookie: sessionid=012345678901234567890123456789012; mode=Display; language=fi^M\nUpgrade-Insecure-Requests: 1^M<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char *dbs_html_get_request_line(unsigned char *name)\n{\n  unsigned char *p;\n\n  FORT_EVENTS_START(308)\n\n  p=htmlin;\n  while(*p!='\\0') {\n    if(!strncmp(p,\"\\r\\n\",2)) {\n      p+=2;\n      if(!strncmp(p,name,strlen(name))) {\n        p+=strlen(name);\n\tif(*p==':') {\n          p++;\n          while(isblank(*p))\n            p++;\n          return(p);\n        }\n      }\n    }\n    p++;\n  }\n  FORT_EVENTS_END(309)\n\n  return(NULL);\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ll\u00e4 haetaan numeerinen html-otsakkeen rivi: (k\u00e4ytet\u00e4\u00e4n Content-Length haussa)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void dbs_html_get_request_line_num(\n    unsigned char *name,\n    int lenbuffer, unsigned char *buffer)\n{\n  int len;\n  unsigned char *n, *p;\n\n  FORT_EVENTS_START(310)\n\n  if((p=dbs_html_get_request_line(name))==NULL)\n    sprintf(buffer,\"0\");\n  else {\n    len=0;\n    n=buffer;\n    while(isdigit(*p)) {\n      if(++len&lt;lenbuffer)\n        *n++=*p;\n      p++;\n    }\n    *n='\\0';\n  }\n  FORT_EVENTS_END(311)\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ll\u00e4 haetaan nimetty cookie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dbs_get_cookie(unsigned char *name,\n    int valuelen, unsigned char *value)\n{\n  int len;\n  unsigned char *p,*n;\n\n  FORT_EVENTS_START(312)\n\n  if((p=dbs_html_get_request_line(\"Cookie\"))==NULL) {\n    return;\n  }\n\n  while(*p!='\\n' &amp;&amp; *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;sizeof(htmlsessionid))\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  FORT_EVENTS_END(313)\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4t\u00e4 k\u00e4ytet\u00e4\u00e4n v\u00e4lily\u00f6nneill\u00e4 erotellun cr-lf loppuisen merkkijonon parsimiseen: Se on l\u00e4hinn\u00e4 k\u00e4yt\u00f6ss\u00e4 html-otsakkeen ensimm\u00e4isell\u00e4 rivill\u00e4 (POST \/app HTTP\/1.1^M)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2)\n{\n  int len;\n  unsigned char *p;\n\n  FORT_EVENTS_START(314)\n\n  p=*p2;\n  len=0;\n  while(!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  FORT_EVENTS_END(315)\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4t\u00e4 k\u00e4ytet\u00e4\u00e4n v\u00e4lily\u00f6nneill\u00e4 erotellun cr-lf loppuisen merkkijoon parsimiseen. Se parsii tiedostopolun tiedostonimen: Se on k\u00e4yt\u00f6ss\u00e4 html-otsakkeen ensimm\u00e4isell\u00e4 rivill\u00e4 (POST \/app HTTP\/1.1^M). Tiedostonimi on tietenkin tiedostopolun viimeisen kauttaviivan j\u00e4lkeinen osa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void dbs_html_parse_filename(int buflen, char *buf,\n  unsigned char *p)\n{\n  int len;\n  unsigned char *n;\n\n  FORT_EVENTS_START(316)\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  FORT_EVENTS_END(317)\n}\n<\/code><\/pre>\n\n\n\n<p>T\u00e4m\u00e4 rutiini hakee tiedoston nimen jatkeen (extension) edellisen kappaleen palauttamasta tiedostonimest\u00e4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void dbs_html_parse_extension(int buflen, char *buf, unsigned char *p)\n{\n  int len;\n  unsigned char *n;\n\n  FORT_EVENTS_START(330)\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  FORT_EVENTS_END(331)\n}<\/code><\/pre>\n\n\n\n<p>Seuraavaa k\u00e4ytet\u00e4\u00e4n html-otsakkeen &#8220;payload&#8221; kent\u00e4n hakuun. Se sis\u00e4lt\u00e4\u00e4 pyynn\u00f6st\u00e4 riippuen joko parametrien arvot tai asiakkaalle palautetun html-sivun rivit. Payload kentt\u00e4 l\u00f6ytyy html-otsakkeen ensimm\u00e4isen &#8220;\\r\\n\\r\\n&#8221;-merkkijonon j\u00e4lkeen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static unsigned char *dbs_html_get_params()\n{\n  int ok=0;\n  unsigned char *p=htmlin;\n\n  FORT_EVENTS_START(318)\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  FORT_EVENTS_END(319)\n\n  if(ok==0)\n    return(NULL);\n  else\n    return(p);\n}<\/code><\/pre>\n\n\n\n<p>Aliohjelmaa k\u00e4ytet\u00e4\u00e4n l\u00e4hinn\u00e4 ohjelman lokien talletuksessa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static 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        ok=1;\n        break;\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}<\/code><\/pre>\n\n\n\n<p>T\u00e4t\u00e4 rutiinia k\u00e4ytet\u00e4\u00e4n https- ja http-palvelimien j\u00e4lkeen ja se hakee yhteyden ja html-otsakkeen tiedot lokien ja asiakasohjelman k\u00e4ytt\u00e4miin kenttiin. Lis\u00e4ksi t\u00e4m\u00e4 ker\u00e4\u00e4 lokitietoja edellisist\u00e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void dba_loop();\n\nstatic void dbs_run_loop()\n{\n  unsigned char *p;\n\n  FORT_EVENTS_START(320)\n\n  p=htmlin;\n  dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&amp;p);\n  fprintf(stdout,\"htmlmethod: \\\"%s\\\"\", htmlmethod);\n  fflush(stdout);\n\n  dbs_html_parse_string(sizeof(htmlpath), htmlpath, &amp;p);\n  fprintf(stdout,\", htmlpath: \\\"%s\\\"\", htmlpath);\n  fflush(stdout);\n\n  dbs_html_parse_string(sizeof(htmlversion), htmlversion, &amp;p);\n  fprintf(stdout,\", htmlversion: \\\"%s\\\"\", htmlversion);\n  fflush(stdout);\n\n  dbs_html_parse_filename(sizeof(htmlfilename), htmlfilename, htmlpath);\n  fprintf(stdout,\", htmlfilename: \\\"%s\\\"\", htmlfilename);\n  fflush(stdout);\n\n  dbs_html_parse_extension(sizeof(htmlextension), htmlextension, htmlfilename);\n  fprintf(stdout,\", htmlextension: \\\"%s\\\"\", htmlextension);\n  fflush(stdout);\n\n  htmlparams=dbs_html_get_params();\n  if(htmlparams==NULL)\n    htmlparams=\"\";\n  fprintf(stdout,\", htmlparamslen: \\\"%ld\\\"\", strlen(htmlparams));\n\n  html_clear_all();\n\n  dba_loop();\n\n  FILE *fp1;\n  char filename&#91;64];\n\n  sprintf(filename,\"%stimelog.deb\",filenamehead);\n  if((fp1=fopen(filename,\"a\"))!=NULL) {\n    fprintf(fp1,\"%s, ip=\\\"%s\\\"\\n\",htmltime, htmlip);\n    fclose(fp1);\n  }\n\n  sprintf(filename,\"%sips.deb\",filenamehead);\n  dbs_add_end_new_str(filename, htmlip);\n\n  sprintf(filename,\"%shostname.deb\",filenamehead);\n  dbs_add_end_new_str(filename, htmlhostname);\n\n  if(htmlsslcipher&#91;0]!='\\0') {\n    sprintf(filename,\"%sciphers.deb\",filenamehead);\n    dbs_add_end_new_str(filename,htmlsslcipher);\n  }\n  sprintf(filename,\"%shtml.deb\",filenamehead);\n  if((fp1 = fopen(filename,\"a\")) != NULL) {\n    fprintf(fp1,\"%s, ip=\\\"%s\\\", callid=\\\"%d\\\"\\n\",htmltime, htmlip, callid);\n    fprintf(fp1,\"%s\\n\",htmlin);\n    for(int c=0;c&lt;HTML_BUFFERS;c++) {\n      if(strlen(html_get_string(c))&gt;0) {\n        fprintf(fp1,\"%d: %s\\n\",c,html_get_string(c));\n      }\n    }\n    fclose(fp1);\n  }\n  fprintf(stdout,\"\\ncallid: %d\\n\", callid++);\n  sprintf(filename,\"%scallid.deb\",filenamehead);\n  if((fp1 = fopen(filename,\"w\")) != NULL) {\n    fprintf(fp1,\"%d\\n\", callid);\n    fclose(fp1);\n  }\n  FORT_EVENTS_END(321)\n}<\/code><\/pre>\n\n\n\n<p>Seuraavana lopun palvelinohjelmien osat, joita k\u00e4ytet\u00e4\u00e4n sek\u00e4 https- ett\u00e4 http-palvelimissa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;errno.h&gt;\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 5\n\nint s,news;\nchar *cert_file = \"cert.pem\";\nchar *privatekey_file = \"key.pem\";\n\nextern char *myport;\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  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  if((s = socket(res-&gt;ai_family, res-&gt;ai_socktype, res-&gt;ai_protocol))==-1) {\n    fprintf(stderr, \"%s: socket(), error: %d\\n\", procname, errno);\n    perror(\"socket\");\n    fflush(stderr);\n  }\n  return(s);\n}\n\nstatic void server_bind(int s, struct addrinfo *res)\n{\n  if(bind(s, res-&gt;ai_addr, res-&gt;ai_addrlen)==-1) {\n    if(errno == 98) {\n      fprintf(stdout,\"%s cannot bind, waiting to bind\", procname);\n      fflush(stdout);\n      while(errno == 98) {\n        sleep(10);\n        fprintf(stdout,\".\");\n        fflush(stdout);\n        bind(s, res-&gt;ai_addr, res-&gt;ai_addrlen);\n      }\n      fprintf(stdout,\"bind done!\\n\");\n      fflush(stdout);\n    } else {\n      fprintf(stderr,\"\\n%s: cannot bind(), error: %d\\n\", procname, errno);\n      perror(\"bind\");\n      fflush(stderr);\n    }\n  }\n}\n\nstatic int server_listen(int s)\n{\n  int listenfd;\n\n  if((listenfd=listen(s,backlog))==-1) {\n    fprintf(stderr,\"\\n%s: cannot listen()\\n\", procname);\n    perror(\"listen\");\n    fflush(stderr);\n  }\n\n  return(listenfd);\n}\n\nstatic void server_close(int s)\n{\n  if(close(s)==-1) {\n    fprintf(stderr,\"\\n%s: cannot close()\\n\", procname);\n    perror(\"close\");\n    fflush(stderr);\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Palvelimiin on lis\u00e4tty metodilla GET ehto, jolloin GET pyynn\u00f6t voivat olla yksi blokkisia.<\/p>\n\n\n\n<p>Seuraavassa http-osuus palvelimesta:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;sys\/socket.h>\n\n#define TIMEFORMAT \"%Z%Y%m%d%H%M%S\"\n#define HTMLTIMEFORMAT \"%a, %d %b %Y %H:%M:%S %Z\"\n\nstatic void http_server()\n{\n  int addr_size;\n\n  struct sockaddr_in sa_cli;\n  struct addrinfo *res;\n\n  unsigned char buffer10&#91;10];\n\n  FORT_EVENTS_START(322)\n\n  \/\/ plus space for '\\0'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \n  htmlin = malloc(htmlinlen+1);\n\n  signal(SIGPIPE, SIG_IGN);\n\n  server_getaddrinfo(myport,&amp;res);\n  s = server_socket(res);\n  server_bind(s,res);\n  freeaddrinfo(res);\n  server_listen(s); \/\/listenfd=server_listen(s);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \n\n\n  for(;;) {\n    FORT_EVENTS_START(323)\n\n    addr_size = sizeof(sa_cli);\n    news = accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size);\n\n    strcpy(htmlip, inet_ntoa(sa_cli.sin_addr));\n    sprintf(htmlport,\"%d\", sa_cli.sin_port);\n    htmlsslcipher&#91;0] = '\\0';\n\n    char host&#91;32], serv&#91;32];\n\n    getnameinfo((struct sockaddr *)&amp;sa_cli,addr_size,host,sizeof(host),serv,sizeof(serv),NI_NUMERICHOST|NI_NUMERICSERV);\n    fprintf(stdout,\" numeric hostname:%s\",host);\n    fprintf(stdout,\" numeric service:%s\",serv);\n\n    getnameinfo((struct sockaddr *)&amp;sa_cli,addr_size,host,sizeof(host),serv,sizeof(serv),NI_NUMERICSERV);\n    fprintf(stdout,\" name hostname:%s\",host);\n    fprintf(stdout,\" service:%s\",serv);\n\n    htmlhostname&#91;0]='\\0';\n\n    unsigned long seconds = dbs_getseconds();\n    strftime(htmltimeshort, sizeof(htmltimeshort), TIMEFORMAT,\n             localtime((time_t *)&amp;seconds));\n    strftime(htmltime, sizeof(htmltime), HTMLTIMEFORMAT,\n             localtime((time_t *)&amp;seconds));\n\n    fprintf(stdout,\"\\nConnection(http) from %x\", sa_cli.sin_addr.s_addr);\n    fprintf(stdout,\", ip %s\", htmlip);\n    fprintf(stdout,\", port %s\", htmlport);\n    fprintf(stdout,\", at %s\\n\", htmltime);\n\n    int clen = 0;\n    int reads = 0;\n    int first = 1;\n    int bytes, totalbytes=0;\n\n    htmlparams = NULL;\n    htmlin&#91;0]='\\0';\n\n    while(htmlparams == NULL ||\n          clen-strlen(htmlparams) > 0) {\n      if(!first) {\n        fprintf(stdout,\", \");\n      }\n      fprintf(stdout,\"read %d\", reads);\n      fflush(stdout);\n      if((bytes=read(news, htmlin+totalbytes, htmlinlen-totalbytes))&lt;0) {\n        fprintf(stderr,\"\\n%s: cannot read()\\n\", procname);\n        perror(\"read\");\n        fflush(stderr);\n      }\n      fprintf(stdout,\"(%d bytes)\", bytes);\n      if(bytes==0)\n        break;\n      if(bytes>3 &amp;&amp;\n         !isprint(htmlin&#91;0]) &amp;&amp;\n         !isprint(htmlin&#91;1]) &amp;&amp;\n         !isprint(htmlin&#91;2])) {\n        fprintf(stdout,\"https packet?\\n\");\n        htmlin&#91;0]='\\0';\n        totalbytes=0;\n        bytes=0;\n        break;\n      }\n      *(htmlin+totalbytes+bytes) = '\\0';\n      fprintf(stdout,\"%s\\n\",htmlin);\n      totalbytes+=bytes;\n      if(totalbytes>=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      reads++;\n      first = 0;\n    }\n    if(totalbytes==0)\n      continue;\n    fprintf(stdout,\"\\n%d reads\", reads);\n    fprintf(stdout,\", received %d chars\", totalbytes);\n    fprintf(stdout,\", read %d total bytes\", totalbytes);\n    fprintf(stdout,\", input buffer size %d chars\", htmlinlen);\n    fprintf(stdout,\", data=\\\"%s\\\"\\n\", htmlin);\n\n    dbs_run_loop();\n\n    for(int c=0;c&lt;HTML_BUFFERS;c++) {\n      if(strlen(html_get_string(c))>0) {\n        if((bytes=write(news, html_get_string(c), strlen(html_get_string(c))))==-1) {\n          fprintf(stderr,\"\\n%s: cannot write() dbs_html&#91;%d]\\n\", procname, c);\n          perror(\"write\");\n          fflush(stderr);\n        }\n      }\n    }\n    server_close(news);\n    fflush(stdout);\n\n    FORT_EVENTS_END(324)\n  }\n  FORT_EVENTS_END(325)\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavaksi https-palvelin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static void https_server()\n{\n  int status, addr_size;\n\n  SSL_METHOD *method=NULL;\n  SSL_CTX *ctx=NULL;\n  SSL *ssl;\n  X509 *peer_cert;\n\n  struct sockaddr_in sa_cli;\n  struct addrinfo *res;\n\n  unsigned char buffer10&#91;10];\n\n  FORT_EVENTS_START(326)\n\n  \/\/ plus space for '\\0'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          \n  htmlin = malloc(htmlinlen+1);\n\n  signal(SIGPIPE, SIG_IGN);\n\n  SSL_library_init();\n\n  OpenSSL_add_ssl_algorithms();\n  OpenSSL_add_all_ciphers();\n\n  SSL_load_error_strings();\n\n\n  if((method = (SSL_METHOD *)\n      SSLv23_server_method()) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\n    fflush(stderr);\n  }\n\n  if((ctx=SSL_CTX_new(method)) == NULL) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\n    fflush(stderr);\n  }\n\n  if(SSL_CTX_use_certificate_file(ctx,\n      cert_file, SSL_FILETYPE_PEM) &lt;= 0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\n    fflush(stderr);\n  }\n\n  if(SSL_CTX_use_PrivateKey_file(ctx,\n      privatekey_file, SSL_FILETYPE_PEM)&lt;=0) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\n    fflush(stderr);\n  }\n\n  if(!SSL_CTX_load_verify_locations(ctx,\n      cert_file, NULL)) {\n    fprintf(stderr,\"\\n%s: cannot SSL_CTX_verify_locations()\", procname);\n    fflush(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); \/\/ listenfd = server_listen(s);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \n\n  for(;;) {\n    FORT_EVENTS_START(327)\n    addr_size = sizeof(sa_cli);\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    strcpy(htmlip, inet_ntoa(sa_cli.sin_addr));\n    sprintf(htmlport,\"%d\", sa_cli.sin_port);\n\n    char host&#91;32], serv&#91;32];\n\n    getnameinfo((struct sockaddr *)&amp;sa_cli,addr_size,host,sizeof(host),serv,sizeof(serv),NI_NUMERICHOST|NI_NUMERICSERV);\n    fprintf(stdout,\" numeric hostname:%s\",host);\n    fprintf(stdout,\" numeric service:%s\",serv);\n\n    getnameinfo((struct sockaddr *)&amp;sa_cli,addr_size,host,sizeof(host),serv,sizeof(serv),NI_NUMERICSERV);\n    fprintf(stdout,\" name hostname:%s\",host);\n    fprintf(stdout,\" service:%s\",serv);\n\n    unsigned long seconds = dbs_getseconds();\n    strftime(htmltimeshort, sizeof(htmltimeshort), TIMEFORMAT,\n             localtime((time_t *)&amp;seconds));\n    strftime(htmltime, sizeof(htmltime), HTMLTIMEFORMAT,\n             localtime((time_t *)&amp;seconds));\n\n\n    fprintf(stdout,\"\\nConnection(https) from %x\", sa_cli.sin_addr.s_addr);\n    fprintf(stdout,\", ip %s\", htmlip);\n    fprintf(stdout,\", port %s\", htmlport);\n    fprintf(stdout,\", at %s\\n\", htmltime);\n\n    if((ssl=SSL_new(ctx)) == NULL) {\n      fprintf(stderr,\"\\n%s: cannot SSL_new()\", procname);\n      fflush(stderr);\n    }\n\n    if(SSL_set_fd(ssl,news) != 1) {\n      fprintf(stderr,\"\\n%s: cannot SSL_set_fd()\", procname);\n      fflush(stderr);\n    }\n\n    int doreadwrite=1,tries=0;\n\n    for(;;) {\n      tries++;\n\n      if(tries>4) {\n        doreadwrite=0;\n        break;\n      }\n\n      status=SSL_accept(ssl);\n      if(status==-1) {\n        int sslerr=SSL_get_error(ssl,status);\n        int saveerrno=errno;\n        fprintf(stderr,\"\\n%s: cannot SSL_accept(), status: %d, SSL error: %d, errno: %d\",\n                procname, status, sslerr, saveerrno);\n        fflush(stderr);\n\n        switch(sslerr) {\n        case SSL_ERROR_WANT_READ:\n          fprintf(stderr,\", sslerr: SSL_ERROR_WANT_READ, retrying\");\n          continue;\n        case SSL_ERROR_WANT_WRITE:\n          fprintf(stderr,\", sslerr: SSL_ERROR_WANT_WRITE, retrying\");\n          continue;\n        case SSL_ERROR_SYSCALL:\n          fprintf(stderr,\", sslerr: SSL_ERROR_SYSCALL(5), errno: %d, retrying\\n\",saveerrno);\n          ERR_print_errors_fp(stderr);\n          continue;\n        }\n      } else\n        break;\n    }\n\n    if(doreadwrite) {\n      peer_cert = SSL_get_peer_certificate(ssl);\n      if(peer_cert == NULL) {\n        fprintf(stdout,\", No peer certificate\");\n        fflush(stdout);\n      }\n\n      fprintf(stdout,\"\\n\");\n\n      int clen = 0;\n      int reads = 0;\n      int first = 1;\n      htmlparams = NULL;\n      int bytes, totalbytes = 0;\n      while(htmlparams==NULL || clen-strlen(htmlparams) > 0) {\n        if(!first) {\n          fprintf(stdout,\", \");\n        }\n        fprintf(stdout,\"read %d\", reads);\n        fflush(stdout);\n        if((bytes = SSL_read(ssl, htmlin+totalbytes, htmlinlen-totalbytes))&lt;0) {\n          fprintf(stderr,\"\\n%s: cannot SSL_read()\\n\", procname);\n          perror(\"SSL_read\");\n          fflush(stderr);\n        }\n        fprintf(stdout,\"(%d bytes)\", bytes);\n        if(bytes==0)\n          break;\n        *(htmlin+totalbytes+bytes) = '\\0';\n\n        totalbytes+=bytes;\n        if(totalbytes >= 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                                      sizeof(buffer10), buffer10);\n        clen = atoi(buffer10);\n        reads++;\n        first = 0;\n      }\n\n      fprintf(stdout,\"\\n%d reads\", reads);\n      fprintf(stdout,\", received %d chars\", totalbytes);\n      fprintf(stdout,\", read %d total bytes\", totalbytes);\n      fprintf(stdout,\", input buffer size %d chars\", htmlinlen);\n      fprintf(stdout,\", data=\\\"%s\\\"\\n\", htmlin);\n\n      strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));\n\n      dbs_run_loop();\n\n      for(int c=0;c&lt;HTML_BUFFERS;c++) {\n        if(strlen(html_get_string(c))>0) {\n          if((status=SSL_write(ssl, html_get_string(c), strlen(html_get_string(c))))&lt;1) {\n            fprintf(stderr,\"\\n%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d\",\n                    procname, c, status, SSL_get_error(ssl,status));\n            fflush(stderr);\n          }\n        }\n      }\n    }\n    fprintf(stdout,\"\\nSSL connection using %s\", htmlsslcipher);\n    fflush(stderr);\n    SSL_free(ssl);\n    server_close(news);\n\n    fflush(stdout);\n    FORT_EVENTS_END(328)\n  } \/\/ for(;;)                                                                                                                                                                                                                                                   \n  SSL_CTX_free(ctx);\n  FORT_EVENTS_END(329)\n}<\/code><\/pre>\n\n\n\n<p>T\u00e4ss\u00e4 rutiini merkkijonon tallettamiseen. K\u00e4ytet\u00e4\u00e4n l\u00e4hinn\u00e4 ohjelman parametreissa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static 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}<\/code><\/pre>\n\n\n\n<p>T\u00e4ll\u00e4 lasketaan tiedoston eli t\u00e4ss\u00e4 ajettavan ohjelman &#8220;sormenj\u00e4lki&#8221;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static 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}<\/code><\/pre>\n\n\n\n<p>Ja varsin p\u00e4\u00e4ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int 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],buffer10&#91;10];\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  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  fprintf(stdout,\"%s\\n\\n\", copyright);\n  fflush(stdout);\n\n  dbs_main(argc,argv);\n  dba_main(argc,argv);\n\n  FILE *fp1;\n  unsigned char filename&#91;64];\n\n  callid = 0;\n\n  sprintf(filename,\"%scallid.deb\",filenamehead);\n  if((fp1 = fopen(filename,\"r\")) != NULL) {\n    fgets(buffer10, sizeof(buffer10), fp1);\n    callid = atoi(buffer10);\n    fclose(fp1);\n  }\n\n  sprintf(filename,\"%spid.deb\",filenamehead);\n  if((fp1 = fopen(filename,\"w\")) != NULL) {\n    fprintf(fp1,\"%d\\n\", getpid());\n    fclose(fp1);\n  }\n\n  if(https)\n    https_server();\n  else\n    http_server();\n\n  exit(0);\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>DBS on tertun palvelinohjelma, joka vastaanottaa asiakkaan selaimelta sivupyynt\u00f6j\u00e4, kutsuu sovellusohjelmaa (DBA), joka muotostaa sivupyynn\u00f6n pohjalta vastauksen. Vastaus palautetaan DBS:lle, joka l\u00e4hett\u00e4\u00e4 tuloksen asiakkaalle. Edit: muutoksia julkaisun j\u00e4lkeen: Palvelimissa on viel\u00e4 ongelmaa Safari-selaimen kanssa, safari menee &#8220;luuppiin&#8221;, jos haetaan sek\u00e4 portillista ja portitonta URL:\u00e4\u00e4 vuorotellen (moijari.com ja moijari.com:5005). .ico (favicon.ico) tiedostopyynt\u00f6jen ohittamista varten lis\u00e4tty muuttuja&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=1522\">Continue reading <span class=\"screen-reader-text\">DBS versio 0.08<\/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\/1522"}],"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=1522"}],"version-history":[{"count":16,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1522\/revisions"}],"predecessor-version":[{"id":1541,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/1522\/revisions\/1541"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}