patch 9.0.1998: xxd: cannot reverse a bit dump

Commit: 
https://github.com/vim/vim/commit/85f4521808dd9a587c00f9a2927e84217721cfca
Author: tristhaus <[email protected]>
Date:   Fri Oct 6 19:51:13 2023 +0200

    patch 9.0.1998: xxd: cannot reverse a bit dump
    
    Problem:  xxd: cannot reverse a bit dump
    Solution: implement reversing the bit dump using -b -r
    
    closes: #13286
    
    Signed-off-by: Christian Brabandt <[email protected]>
    Co-authored-by: tristhaus <[email protected]>

diff --git a/runtime/doc/xxd-fr.1 b/runtime/doc/xxd-fr.1
index e170df5d7..7aa3ff1a6 100644
--- a/runtime/doc/xxd-fr.1
+++ b/runtime/doc/xxd-fr.1
@@ -70,7 +70,7 @@ Convertit en binaires plut
 Cette option écrit les octets comme une séquence de "1" et de "0" au lieu
 d'une conversion en hexadécimal traditionnel. Chaque ligne est précédée par un
 numéro de ligne en hexadécimal et suivie de la représentation ASCII (ou
-EBCDIC) correspondante. Les options \-r, \-p, \-i ne fonctionnent pas dans ce
+EBCDIC) correspondante. Les options \-p, \-i ne fonctionnent pas dans ce
 mode.
 .TP
 .IR "\-c cols " | " \-cols cols"
diff --git a/runtime/doc/xxd-fr.UTF-8.1 b/runtime/doc/xxd-fr.UTF-8.1
index 47773a136..9c4c4c928 100644
--- a/runtime/doc/xxd-fr.UTF-8.1
+++ b/runtime/doc/xxd-fr.UTF-8.1
@@ -70,7 +70,7 @@ Convertit en binaires plutôt qu'en hexadécimal.
 Cette option écrit les octets comme une séquence de "1" et de "0" au lieu
 d'une conversion en hexadécimal traditionnel. Chaque ligne est précédée 
par un
 numéro de ligne en hexadécimal et suivie de la représentation ASCII (ou
-EBCDIC) correspondante. Les options \-r, \-p, \-i ne fonctionnent pas dans ce
+EBCDIC) correspondante. Les options \-p, \-i ne fonctionnent pas dans ce
 mode.
 .TP
 .IR "\-c cols " | " \-cols cols"
diff --git a/runtime/doc/xxd-it.1 b/runtime/doc/xxd-it.1
index 9034fddc3..ed4fd8194 100644
--- a/runtime/doc/xxd-it.1
+++ b/runtime/doc/xxd-it.1
@@ -63,7 +63,7 @@ Richiesta di omissione: Un singolo '*' rimpiazza righe a zeri 
binari. Default: o
 Richiesta di un'immagine binaria (cifre binarie), invece che esadecimale.
 Quest'opzione scrive un byte come otto cifre "1" e "0" invece di usare i
 numeri esadecimali. Ogni riga è preceduta da un indirizzo in esadecimale e
-seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-r, \-p, \-i,
+seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-p, \-i,
 specificabili dalla riga comando, non funzionano in questo modo.
 .TP
 .IR "\-c colonne " | " \-cols colonne"
diff --git a/runtime/doc/xxd-it.UTF-8.1 b/runtime/doc/xxd-it.UTF-8.1
index b982a2c9d..8653de972 100644
--- a/runtime/doc/xxd-it.UTF-8.1
+++ b/runtime/doc/xxd-it.UTF-8.1
@@ -63,7 +63,7 @@ Richiesta di omissione: Un singolo '*' rimpiazza righe a zeri 
binari. Default: o
 Richiesta di un'immagine binaria (cifre binarie), invece che esadecimale.
 Quest'opzione scrive un byte come otto cifre "1" e "0" invece di usare i
 numeri esadecimali. Ogni riga è preceduta da un indirizzo in esadecimale e
-seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-r, \-p, \-i,
+seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-p, \-i,
 specificabili dalla riga comando, non funzionano in questo modo.
 .TP
 .IR "\-c colonne " | " \-cols colonne"
diff --git a/runtime/doc/xxd-ja.UTF-8.1 b/runtime/doc/xxd-ja.UTF-8.1
index a03671cb1..1e06bde81 100644
--- a/runtime/doc/xxd-ja.UTF-8.1
+++ b/runtime/doc/xxd-ja.UTF-8.1
@@ -58,7 +58,7 @@
 1 オクテット㠌 "1" 㠨 "0" 㠮 8 文字㠧出力㠕れ㠾㠙。
 å „è¡Œã ®è¡Œé ­ã «ã ¯ 16 é€²æ•°ã ®è¡Œç•ªå ·ã Œè¡¨ç¤ºã •ã‚Œã ¾ã ™ã€‚
 行末㠫㠯 ascii (㠾㠟㠯 ebcdic) ã §è¡¨ã —ã Ÿå ´å ˆã ®æ–‡å­—ã Œè¡¨ç¤ºã 
•れ㠾㠙。
-㠓㠮モード㠧㠯 \-r〠\-p〠\-i 㠯機能㠗㠾㠛ん。
+㠓㠮モード㠧㠯 \-p〠\-i 㠯機能㠗㠾㠛ん。
 .TP
 .IR \-e
 リトルエンディアン㠮 16 進ダンプ㠫切り替㠈る。
diff --git a/runtime/doc/xxd-pl.1 b/runtime/doc/xxd-pl.1
index d9fa9be20..877b7e45f 100644
--- a/runtime/doc/xxd-pl.1
+++ b/runtime/doc/xxd-pl.1
@@ -66,7 +66,7 @@ Prze
 Opcja ta zapisuje oktety jako osiem cyfr 1 lub 0 zamiast normalnego
 zrzutu heksowego. Ka¿da linia jest poprzedzona przez
 heksadecymalny numer linii a po nim jego reprezentacj± w ascii (lub
-ebcdic). Opcje linii poleceñ \-r, \-p, \-i nie dzia³aj± w tym
+ebcdic). Opcje linii poleceñ \-p, \-i nie dzia³aj± w tym
 trybie.
 .TP
 .IR "\-c cols " | " \-cols cols"
diff --git a/runtime/doc/xxd-pl.UTF-8.1 b/runtime/doc/xxd-pl.UTF-8.1
index e63ce64b7..a28dd6377 100644
--- a/runtime/doc/xxd-pl.UTF-8.1
+++ b/runtime/doc/xxd-pl.UTF-8.1
@@ -66,7 +66,7 @@ Przełącza do zrzutu bitowego (cyfr binarnych) zamiast 
heksowego.
 Opcja ta zapisuje oktety jako osiem cyfr 1 lub 0 zamiast normalnego
 zrzutu heksowego. Każda linia jest poprzedzona przez
 heksadecymalny numer linii a po nim jego reprezentacjÄ… w ascii (lub
-ebcdic). Opcje linii poleceń \-r, \-p, \-i nie działają w tym
+ebcdic). Opcje linii poleceń \-p, \-i nie działają w tym
 trybie.
 .TP
 .IR "\-c cols " | " \-cols cols"
diff --git a/runtime/doc/xxd-ru.1 b/runtime/doc/xxd-ru.1
index 111946ab5..8f324327b 100644
--- a/runtime/doc/xxd-ru.1
+++ b/runtime/doc/xxd-ru.1
@@ -70,7 +70,7 @@ xxd 
 ðÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÜÔÏÇÏ ËÌÀÞÁ ×ÍÅÓÔÏ ÏÂÙÞÎÏÇÏ ÛÅÓÔÎÁÄÃÁÔÅÒÉÞÎÏÇÏ ÐÒÅÄÓÔÁ×ÌÅÎÉÑ
 ÏËÔÅÔÏ× ÉÓÐÏÌØÚÕÀÔÓÑ ÎÁÂÏÒÙ ÉÚ ×ÏÓØÍÉ ÓÉÍ×ÏÌÏ× "1" É "0". ëÁÖÄÁÑ ÓÔÒÏËÁ
 ÐÒÅÄ×ÁÒÑÅÔÓÑ ÎÏÍÅÒÏÍ ÓÔÒÏËÉ × ÛÅÓÔÎÁÄÃÁÔÅÒÉÞÎÏÍ ×ÉÄÅ, Á ÚÁ×ÅÒÛÁÅÔÓÑ ÓÉÍ×ÏÌØÎÙÍ 
-ÐÒÅÄÓÔÁ×ÌÅÎÉÅÍ (× ×ÉÄÅ ascii ÉÌÉ ebcdic). ëÌÀÞÉ \-r, \-p, \-i × ÜÔÏÍ ÒÅÖÉÍÅ
+ÐÒÅÄÓÔÁ×ÌÅÎÉÅÍ (× ×ÉÄÅ ascii ÉÌÉ ebcdic). ëÌÀÞÉ \-p, \-i × ÜÔÏÍ ÒÅÖÉÍÅ
 ÎÅ ÒÁÂÏÔÁÀÔ.
 .TP
 .IR "\-c ËÏÌ " | " \-cols ËÏÌ"
diff --git a/runtime/doc/xxd-ru.UTF-8.1 b/runtime/doc/xxd-ru.UTF-8.1
index 647845bab..4a41d66db 100644
--- a/runtime/doc/xxd-ru.UTF-8.1
+++ b/runtime/doc/xxd-ru.UTF-8.1
@@ -70,7 +70,7 @@ xxd Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñ ÐµÑ‚ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñ Ñ‚ÑŒ 
декодирование в пото
 При Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ð¸ Ñ Ñ‚Ð¾Ð³Ð¾ ключа Ð²Ð¼ÐµÑ Ñ‚Ð¾ 
обычного ÑˆÐµÑ Ñ‚Ð½Ð°Ð´Ñ†Ð°Ñ‚ÐµÑ€Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ Ð¿Ñ€ÐµÐ´Ñ Ñ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ 
 октетов Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·ÑƒÑŽÑ‚Ñ Ñ  наборы из Ð²Ð¾Ñ ÑŒÐ¼Ð¸ Ñ 
имволов "1" и "0". ÐšÐ°Ð¶Ð´Ð°Ñ  Ñ Ñ‚Ñ€Ð¾ÐºÐ°
 Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ñ ÐµÑ‚Ñ Ñ  номером Ñ Ñ‚Ñ€Ð¾ÐºÐ¸ в ÑˆÐµÑ 
тнадцатеричном виде, а Ð·Ð°Ð²ÐµÑ€ÑˆÐ°ÐµÑ‚Ñ Ñ  Ñ 
имвольным 
-Ð¿Ñ€ÐµÐ´Ñ Ñ‚Ð°Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ (в виде ascii или ebcdic). Ключи 
\-r, \-p, \-i в Ñ Ñ‚Ð¾Ð¼ режиме
+Ð¿Ñ€ÐµÐ´Ñ Ñ‚Ð°Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ (в виде ascii или ebcdic). Ключи 
\-p, \-i в Ñ Ñ‚Ð¾Ð¼ режиме
 не работают.
 .TP
 .IR "\-c кол " | " \-cols кол"
diff --git a/runtime/doc/xxd.1 b/runtime/doc/xxd.1
index 7cd6ae8c7..f5a7c6589 100644
--- a/runtime/doc/xxd.1
+++ b/runtime/doc/xxd.1
@@ -64,7 +64,7 @@ Switch to bits (binary digits) dump, rather than hex dump.
 This option writes octets as eight digits "1"s and "0"s instead of a normal
 hexadecimal dump. Each line is preceded by a line number in hexadecimal and
 followed by an ASCII (or EBCDIC) representation. The command line switches
-\-r, \-p, \-i do not work with this mode.
+\-p, \-i do not work with this mode.
 .TP
 .IR "\-c cols " | " \-cols cols"
 Format
@@ -133,7 +133,9 @@ it. Use the combination
 .I \-r \-p
 to read plain hexadecimal dumps without line number information and without a
 particular column layout. Additional whitespace and line breaks are allowed
-anywhere.
+anywhere. Use the combination
+.I \-r \-b
+to read a bits dump instead of a hex dump.
 .TP
 .IR \-R " " when
 In output the hex-value and the value are both colored with the same color
diff --git a/runtime/doc/xxd.man b/runtime/doc/xxd.man
index 06cc784c4..56b69b434 100644
--- a/runtime/doc/xxd.man
+++ b/runtime/doc/xxd.man
@@ -37,7 +37,7 @@ OPTIONS
               option  writes octets as eight digits "1"s and "0"s instead of a
               normal hexadecimal dump. Each line is preceded by a line  number
               in  hexadecimal and followed by an ASCII (or EBCDIC) 
representa†
-              tion. The command line switches -r, -p, -i do not work with this
+              tion. The command line switches -p, -i do  not  work  with  this
               mode.
 
        -c cols | -cols cols
@@ -97,7 +97,8 @@ OPTIONS
               truncating it. Use the combination -r -p to read plain 
hexadeci†
               mal dumps without line number information and without a 
particu†
               lar column layout. Additional whitespace and line breaks are 
al†
-              lowed anywhere.
+              lowed anywhere.  Use the combination -r -b to read a  bits  dump
+              instead of a hex dump.
 
        -R when
               In  output the hex-value and the value are both colored with the
diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim
index 3c12899bf..53e1a95c3 100644
--- a/src/testdir/test_xxd.vim
+++ b/src/testdir/test_xxd.vim
@@ -312,6 +312,31 @@ func Test_xxd_patch()
   call delete('Xxxdout')
 endfunc
 
+func Test_xxd_patch_with_bitdump()
+  let cmd1 = 'silent !' .. s:xxd_cmd .. ' -r -b Xxxdin Xxxdfile'
+  let cmd2 = 'silent !' .. s:xxd_cmd .. ' -g1 Xxxdfile > Xxxdout'
+
+  call writefile(["2: 01000001 01000001", "8: 01000010 01000010"], 'Xxxdin', 
'D')
+  call writefile(['::::::::'], 'Xxxdfile', 'D')
+  exe cmd1
+  exe cmd2
+  call assert_equal(['00000000: 3a 3a 41 41 3a 3a 3a 3a 42 42                  
  ::AA::::BB'], readfile('Xxxdout'))
+
+  call writefile(["1: 01000011 01000011", "4: 01000100 01000100"], 'Xxxdin', 
'D')
+  call writefile(['::::::::'], 'Xxxdfile', 'D')
+  exe cmd1
+  exe cmd2
+  call assert_equal(['00000000: 3a 43 43 3a 44 44 3a 3a 0a                     
  :CC:DD::.'], readfile('Xxxdout'))
+
+  call writefile(["02: 01000101 01000101", "08: 01000110 01000110"], 'Xxxdin', 
'D')
+  call writefile(['::::::::'], 'Xxxdfile', 'D')
+  exe cmd1
+  exe cmd2
+  call assert_equal(['00000000: 3a 3a 45 45 3a 3a 3a 3a 46 46                  
  ::EE::::FF'], readfile('Xxxdout'))
+
+  call delete('Xxxdout')
+endfunc
+
 " Various ways with wrong arguments that trigger the usage output.
 func Test_xxd_usage()
   for arg in ['-h', '-c', '-g', '-o', '-s', '-l', '-X', '-R', 'one two three']
@@ -336,6 +361,18 @@ func Test_xxd_bit_dump()
   bwipe!
 endfunc
 
+func Test_xxd_revert_bit_dump()
+  new
+  exe 'r! printf "00000000: 01000001 01100010 01000011 01100100 01000101 
01100110 01000111 01101000  AbCdEfGh" | ' . s:xxd_cmd . ' -r -b1 -c 8'
+  call assert_match('AbCdEfGh', join(getline(1, 3)))
+  bwipe!
+
+  new
+  exe 'r! printf "00000000: 01000001 01100010 01000011 01100100 01000101 
01100110  AbCdEf
00000006: 01000111 01101000                                      Gh
" | ' . s:xxd_cmd . ' -r -b1'
+  call assert_match('AbCdEfGh', join(getline(1, 3)))
+  bwipe!
+endfunc
+
 func Test_xxd_version()
   new
   exe 'r! ' . s:xxd_cmd . ' -v'
diff --git a/src/version.c b/src/version.c
index a946279ec..5335352b0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1998,
 /**/
     1997,
 /**/
diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c
index 1ba22477f..56fb32183 100644
--- a/src/xxd/xxd.c
+++ b/src/xxd/xxd.c
@@ -57,6 +57,7 @@
  * 14.01.2022  Disable extra newlines with -c0 -p by Erik Auerswald.
  * 20.06.2022  Permit setting the variable names used by -i by David Gow
  * 31.08.2023  -R never/auto/always prints colored output
+ * 06.10.2023  enable -r -b to reverse bit dumps
  *
  * (c) 1990-1998 by Juergen Weigert ([email protected])
  *
@@ -135,7 +136,7 @@ extern void perror __P((char *));
 # endif
 #endif
 
-char version[] = "xxd 2023-09-04 by Juergen Weigert et al.";
+char version[] = "xxd 2023-10-06 by Juergen Weigert et al.";
 #ifdef WIN32
 char osver[] = " (Win32)";
 #else
@@ -234,7 +235,7 @@ exit_with_usage(void)
   fprintf(stderr, "    or
       %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]
", pname);
   fprintf(stderr, "Options:
");
   fprintf(stderr, "    -a          toggle autoskip: A single '*' replaces 
nul-lines. Default off.
");
-  fprintf(stderr, "    -b          binary digit dump (incompatible with 
-ps,-i,-r). Default hex.
");
+  fprintf(stderr, "    -b          binary digit dump (incompatible with 
-ps,-i). Default hex.
");
   fprintf(stderr, "    -C          capitalize variable names in C include file 
style (-i).
");
   fprintf(stderr, "    -c cols     format <cols> octets per line. Default 16 
(-i: 12, -ps: 30).
");
   fprintf(stderr, "    -E          show characters in EBCDIC. Default ASCII.
");
@@ -324,6 +325,17 @@ parse_hex_digit(int c)
        : -1;
 }
 
+/*
+ * If "c" is a bin digit, return the value.
+ * Otherwise return -1.
+ */
+  static int
+parse_bin_digit(int c)
+{
+  return (c >= '0' && c <= '1') ? c - '0'
+        : -1;
+}
+
 /*
  * Ignore text on "fpi" until end-of-line or end-of-file.
  * Return the '
' or EOF character.
@@ -352,7 +364,7 @@ huntype(
   int hextype,
   long base_off)
 {
-  int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols;
+  int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols, bt, b = 0, bcnt = 0;
   long have_off = 0, want_off = 0;
 
   rewind(fpi);
@@ -368,25 +380,60 @@ huntype(
       if (hextype == HEX_POSTSCRIPT && (c == ' ' || c == '
' || c == '     '))
        continue;
 
-      n3 = n2;
-      n2 = n1;
+      if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT)
+        {
+         n3 = n2;
+         n2 = n1;
 
-      n1 = parse_hex_digit(c);
-      if (n1 == -1 && ign_garb)
-       continue;
+         n1 = parse_hex_digit(c);
+         if (n1 == -1 && ign_garb)
+           continue;
+        }
+      else /* HEX_BITS */
+        {
+         n1 = parse_hex_digit(c);
+         if (n1 == -1 && ign_garb)
+           continue;
+
+          bt = parse_bin_digit(c);
+          if (bt != -1)
+            {
+              b = ((b << 1) | bt);
+              ++bcnt;
+            }
+        }
 
       ign_garb = 0;
 
-      if (!hextype && (p >= cols))
+      if ((hextype != HEX_POSTSCRIPT) && (p >= cols))
        {
-         if (n1 < 0)
-           {
-             p = 0;
-             continue;
-           }
-         want_off = (want_off << 4) | n1;
-         continue;
-       }
+          if (hextype == HEX_NORMAL)
+            {
+             if (n1 < 0)
+               {
+                 p = 0;
+                 continue;
+               }
+             want_off = (want_off << 4) | n1;
+            }
+          else /* HEX_BITS */
+            {
+              n1 = parse_hex_digit(c);
+              if (n1 >= 0)
+                {
+                  want_off = (want_off << 4) | n1;
+                }
+
+              if (bt < 0)
+                {
+                  p = 0;
+                  bcnt = 0;
+                  b = 0;
+                  continue;
+                }
+            }
+          continue;
+        }
 
       if (base_off + want_off != have_off)
        {
@@ -402,23 +449,40 @@ huntype(
            putc_or_die(0, fpo);
        }
 
-      if (n2 >= 0 && n1 >= 0)
-       {
-         putc_or_die((n2 << 4) | n1, fpo);
-         have_off++;
-         want_off++;
-         n1 = -1;
-         if (!hextype && (++p >= cols))
-           /* skip the rest of the line as garbage */
-           c = skip_to_eol(fpi, c);
-       }
-      else if (n1 < 0 && n2 < 0 && n3 < 0)
-        /* already stumbled into garbage, skip line, wait and see */
-       c = skip_to_eol(fpi, c);
+      if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT)
+        {
+          if (n2 >= 0 && n1 >= 0)
+            {
+              putc_or_die((n2 << 4) | n1, fpo);
+              have_off++;
+              want_off++;
+              n1 = -1;
+              if (!hextype && (++p >= cols))
+              /* skip the rest of the line as garbage */
+              c = skip_to_eol(fpi, c);
+            }
+          else if (n1 < 0 && n2 < 0 && n3 < 0)
+            /* already stumbled into garbage, skip line, wait and see */
+            c = skip_to_eol(fpi, c);
+        }
+      else /* HEX_BITS */
+        {
+          if (bcnt == 8)
+            {
+              putc_or_die(b, fpo);
+              have_off++;
+              want_off++;
+              b = 0;
+              bcnt = 0;
+              if (++p >= cols)
+                /* skip the rest of the line as garbage */
+                 c = skip_to_eol(fpi, c);
+            }
+        }
 
       if (c == '
')
        {
-         if (!hextype)
+         if (hextype == HEX_NORMAL || hextype == HEX_BITS)
            want_off = 0;
          p = cols;
          ign_garb = 1;
@@ -847,12 +911,17 @@ main(int argc, char *argv[])
     }
 
   if (revert)
-    {
-      if (hextype && (hextype != HEX_POSTSCRIPT))
-       error_exit(-1, "Sorry, cannot revert this type of hexdump");
-      return huntype(fp, fpo, cols, hextype,
-               negseek ? -seekoff : seekoff);
-    }
+    switch (hextype)
+      {
+      case HEX_NORMAL:
+      case HEX_POSTSCRIPT:
+      case HEX_BITS:
+        return huntype(fp, fpo, cols, hextype,
+          negseek ? -seekoff : seekoff);
+        break;
+      default:
+        error_exit(-1, "Sorry, cannot revert this type of hexdump");
+      }
 
   if (seekoff || negseek || !relseek)
     {

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qop7N-00ArdI-5Q%40256bit.org.

Raspunde prin e-mail lui