->b[7] = (
UChar)((hi32 >> 24) & 0xFF);
241 n->b[6] = (
UChar)((hi32 >> 16) & 0xFF);
242 n->b[5] = (
UChar)((hi32 >> 8) & 0xFF);
243 n->b[4] = (
UChar) (hi32 & 0xFF);
244 n->b[3] = (
UChar)((lo32 >> 24) & 0xFF);
245 n->b[2] = (
UChar)((lo32 >> 16) & 0xFF);
246 n->b[1] = (
UChar)((lo32 >> 8) & 0xFF);
247 n->b[0] = (
UChar) (lo32 & 0xFF);
257 for(
i= 0;
i< 8;
i++) {
258sum += base * (double)(
n->b[
i]);
269 for(
i= 0;
i< 8;
i++)
270 if(
n->b[
i] != 0)
return0;
282 for(
i= 7;
i>= 0;
i--) {
283 tmp= rem * 256 +
n->b[
i];
284 n->b[
i] =
tmp/ 10;
303 buf[nBuf] = q +
'0';
307 for(
i= 0;
i< nBuf;
i++)
321 if(c == EOF)
return True;
334 UInt32nbytes_in_lo32, nbytes_in_hi32;
335 UInt32nbytes_out_lo32, nbytes_out_hi32;
336 Int32bzerr, bzerr_dummy, ret;
341 if(ferror(stream))
gotoerrhandler_io;
342 if(ferror(zStream))
gotoerrhandler_io;
346 if(bzerr !=
BZ_OK)
gotoerrhandler;
348 if(
verbosity>= 2) fprintf ( stderr,
"\n");
352 if(
myfeof(stream))
break;
353nIbuf = fread ( ibuf,
sizeof(
UChar), 5000, stream );
354 if(ferror(stream))
gotoerrhandler_io;
355 if(nIbuf > 0)
BZ2_bzWrite( &bzerr, bzf, (
void*)ibuf, nIbuf );
356 if(bzerr !=
BZ_OK)
gotoerrhandler;
361&nbytes_in_lo32, &nbytes_in_hi32,
362&nbytes_out_lo32, &nbytes_out_hi32 );
363 if(bzerr !=
BZ_OK)
gotoerrhandler;
365 if(ferror(zStream))
gotoerrhandler_io;
366ret = fflush ( zStream );
367 if(ret == EOF)
gotoerrhandler_io;
368 if(zStream != stdout) {
369 Int32fd = fileno ( zStream );
370 if(fd < 0)
gotoerrhandler_io;
372ret = fclose ( zStream );
374 if(ret == EOF)
gotoerrhandler_io;
377 if(ferror(stream))
gotoerrhandler_io;
378ret = fclose ( stream );
379 if(ret == EOF)
gotoerrhandler_io;
382 if(nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
383fprintf ( stderr,
" no data compressed.\n");
385 Charbuf_nin[32], buf_nout[32];
386 UInt64nbytes_in, nbytes_out;
387 doublenbytes_in_d, nbytes_out_d;
389nbytes_in_lo32, nbytes_in_hi32 );
391nbytes_out_lo32, nbytes_out_hi32 );
396fprintf ( stderr,
"%6.3f:1, %6.3f bits/byte, " 397 "%5.2f%% saved, %s in, %s out.\n",
398nbytes_in_d / nbytes_out_d,
399(8.0 * nbytes_out_d) / nbytes_in_d,
400100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
411&nbytes_in_lo32, &nbytes_in_hi32,
412&nbytes_out_lo32, &nbytes_out_hi32 );
422 panic(
"compress:unexpected error");
425 panic(
"compress:end");
436 Int32bzerr, bzerr_dummy, ret, nread, streamNo,
i;
449 if(ferror(stream))
gotoerrhandler_io;
450 if(ferror(zStream))
gotoerrhandler_io;
458 if(bzf ==
NULL|| bzerr !=
BZ_OK)
gotoerrhandler;
461 while(bzerr ==
BZ_OK) {
462nread =
BZ2_bzRead( &bzerr, bzf, obuf, 5000 );
465fwrite ( obuf,
sizeof(
UChar), nread, stream );
466 if(ferror(stream))
gotoerrhandler_io;
471 if(bzerr !=
BZ_OK)
panic(
"decompress:bzReadGetUnused");
473unusedTmp = (
UChar*)unusedTmpV;
474 for(
i= 0;
i< nUnused;
i++)
unused[
i] = unusedTmp[
i];
477 if(bzerr !=
BZ_OK)
panic(
"decompress:bzReadGetUnused");
479 if(nUnused == 0 &&
myfeof(zStream))
break;
483 if(ferror(zStream))
gotoerrhandler_io;
484 if(stream != stdout) {
485 Int32fd = fileno ( stream );
486 if(fd < 0)
gotoerrhandler_io;
489ret = fclose ( zStream );
490 if(ret == EOF)
gotoerrhandler_io;
492 if(ferror(stream))
gotoerrhandler_io;
493ret = fflush ( stream );
494 if(ret != 0)
gotoerrhandler_io;
495 if(stream != stdout) {
496ret = fclose ( stream );
498 if(ret == EOF)
gotoerrhandler_io;
501 if(
verbosity>= 2) fprintf ( stderr,
"\n ");
508 if(
myfeof(zStream))
break;
509nread = fread ( obuf,
sizeof(
UChar), 5000, zStream );
510 if(ferror(zStream))
gotoerrhandler_io;
511 if(nread > 0) fwrite ( obuf,
sizeof(
UChar), nread, stream );
512 if(ferror(stream))
gotoerrhandler_io;
532 if(zStream != stdin) fclose(zStream);
533 if(stream != stdout) fclose(stream);
539 "\n%s: %s: trailing garbage after EOF ignored\n",
544 panic(
"decompress:unexpected error");
547 panic(
"decompress:end");
557 Int32bzerr, bzerr_dummy, ret, streamNo,
i;
568 if(ferror(zStream))
gotoerrhandler_io;
576 if(bzf ==
NULL|| bzerr !=
BZ_OK)
gotoerrhandler;
579 while(bzerr ==
BZ_OK) {
586 if(bzerr !=
BZ_OK)
panic(
"test:bzReadGetUnused");
588unusedTmp = (
UChar*)unusedTmpV;
589 for(
i= 0;
i< nUnused;
i++)
unused[
i] = unusedTmp[
i];
592 if(bzerr !=
BZ_OK)
panic(
"test:bzReadGetUnused");
593 if(nUnused == 0 &&
myfeof(zStream))
break;
597 if(ferror(zStream))
gotoerrhandler_io;
598ret = fclose ( zStream );
599 if(ret == EOF)
gotoerrhandler_io;
601 if(
verbosity>= 2) fprintf ( stderr,
"\n ");
616 "data integrity (CRC) error in data\n");
622 "file ends unexpectedly\n");
625 if(zStream != stdin) fclose(zStream);
628 "bad magic number (file not created by bzip2)\n");
633 "trailing garbage after EOF ignored\n");
637 panic(
"test:unexpected error");
640 panic(
"test:end");
664 "\nIt is possible that the compressed file(s) have become corrupted.\n" 665 "You can use the -tvv option to test integrity of such files.\n\n" 666 "You can use the `bzip2recover' program to attempt to recover\n" 667 "data from undamaged sections of corrupted files.\n\n" 679 "\tInput file = %s, output file = %s\n",
705 "%s: Deleting output file %s, if it exists.\n",
712 "%s: WARNING: deletion of output file " 713 "(apparently) failed.\n",
717 "%s: WARNING: deletion of output file suppressed\n",
720 "%s: since input file no longer exists. Output file\n",
723 "%s: `%s' may be incomplete.\n",
726 "%s: I suggest doing an integrity test (bzip2 -tv)" 734 "%s: WARNING: some files have not been processed:\n" 735 "%s: %d specified on command line, %d not processed yet.\n\n",
749 "\n%s: PANIC -- internal consistency error:\n" 751 "\tThis is a BUG. Please report it to:\n" 752 "\tbzip2-devel@sourceware.org\n",
764 "\n%s: Data integrity error when decompressing.\n",
778 "\n%s: Compressed file ends unexpectedly;\n\t" 779 "perhaps it is corrupted? *Possible* reason follows.\n",
794 "\n%s: I/O or other error, bailing out. " 795 "Possible reason follows.\n",
808 "\n%s: Control-C or similar caught, quitting.\n",
821 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n" 823 " Possible causes are (most likely first):\n" 824 " (1) This computer has unreliable memory or cache hardware\n" 825 " (a surprisingly common problem; try a different machine.)\n" 826 " (2) A bug in the compiler used to create this executable\n" 827 " (unlikely, if you didn't compile bzip2 yourself.)\n" 828 " (3) A real bug in bzip2 -- I hope this should never be the case.\n" 829 " The user's manual, Section 4.3, has more info on (1) and (2).\n" 831 " If you suspect this is a bug in bzip2, or are unsure about (1)\n" 832 " or (2), feel free to report it to: bzip2-devel@sourceware.org.\n" 833 " Section 4.3 of the user's manual describes the info a useful\n" 834 " bug report should have. If the manual is available on your\n" 835 " system, please try and read it before mailing me. If you don't\n" 836 " have the manual or can't be bothered to read it, mail me anyway.\n" 842 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n" 844 " Possible causes are (most likely first):\n" 845 " (1) The compressed data is corrupted, and bzip2's usual checks\n" 846 " failed to detect this. Try bzip2 -tvv my_file.bz2.\n" 847 " (2) This computer has unreliable memory or cache hardware\n" 848 " (a surprisingly common problem; try a different machine.)\n" 849 " (3) A bug in the compiler used to create this executable\n" 850 " (unlikely, if you didn't compile bzip2 yourself.)\n" 851 " (4) A real bug in bzip2 -- I hope this should never be the case.\n" 852 " The user's manual, Section 4.3, has more info on (2) and (3).\n" 854 " If you suspect this is a bug in bzip2, or are unsure about (2)\n" 855 " or (3), feel free to report it to: bzip2-devel@sourceware.org.\n" 856 " Section 4.3 of the user's manual describes the info a useful\n" 857 " bug report should have. If the manual is available on your\n" 858 " system, please try and read it before mailing me. If you don't\n" 859 " have the manual or can't be bothered to read it, mail me anyway.\n" 875 "\n%s: couldn't allocate enough memory\n",
887 "bzip2: I'm not configured correctly for this platform!\n" 888 "\tI require Int32, Int16 and Char to have sizes\n" 889 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n" 890 "\tProbably you can fix this by defining them correctly,\n" 891 "\tand recompiling. Bye!\n");
913fprintf ( stderr,
" ");
924 "bzip2: file name\n`%s'\n" 925 "is suspiciously (more than %d chars) long.\n" 926 "Try using a reasonable file name instead. Sorry! :-)\n",
942FILE *
tmp= fopen ( name,
"rb");
965fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
966 if(fh == -1)
return NULL;
971 returnfopen(name,
mode);
987 if(
i!= 0)
return True;
1004 if(
i!= 0)
return0;
1005 return(statBuf.st_nlink - 1);
1054 structutimbuf uTimBuf;
1059retVal = utime ( dstName, &uTimBuf );
1094 for(; *name !=
'\0'; name++)
1095 if(*name ==
'?'|| *name ==
'*')
return True;
1102 #define BZ_N_SUFFIX_PAIRS 4 1105= {
".bz2",
".bz",
".tbz2",
".tbz"};
1107= {
"",
"",
".tar",
".tar"};
1112 Int32ns = strlen(s);
1113 Int32nx = strlen(suffix);
1114 if(ns < nx)
return False;
1115 if(
strcmp(s + ns - nx, suffix) == 0)
return True;
1121 const Char* oldSuffix,
1122 const Char* newSuffix )
1125name[strlen(name)-strlen(oldSuffix)] = 0;
1126 strcat( name, newSuffix );
1143 panic(
"compress: bad modes\n");
1163fprintf ( stderr,
"%s: There are no files matching `%s'.\n",
1169fprintf ( stderr,
"%s: Can't open input file %s: %s.\n",
1178 "%s: Input file %s already has %s suffix.\n",
1188 "%s: Input file %s is a directory.\n",
1196fprintf ( stderr,
"%s: Input file %s is not a normal file.\n",
1205fprintf ( stderr,
"%s: Output file %s already exists.\n",
1213fprintf ( stderr,
"%s: Input file %s has %d other link%s.\n",
1230 if( isatty ( fileno ( stdout ) ) ) {
1232 "%s: I won't write compressed data to a terminal.\n",
1234fprintf ( stderr,
"%s: For help, type: `%s --help'.\n",
1242inStr = fopen (
inName,
"rb");
1244 if( isatty ( fileno ( stdout ) ) ) {
1246 "%s: I won't write compressed data to a terminal.\n",
1248fprintf ( stderr,
"%s: For help, type: `%s --help'.\n",
1250 if( inStr !=
NULL) fclose ( inStr );
1254 if( inStr ==
NULL) {
1255fprintf ( stderr,
"%s: Can't open input file %s: %s.\n",
1263inStr = fopen (
inName,
"rb");
1265 if( outStr ==
NULL) {
1266fprintf ( stderr,
"%s: Can't create output file %s: %s.\n",
1268 if( inStr !=
NULL) fclose ( inStr );
1272 if( inStr ==
NULL) {
1273fprintf ( stderr,
"%s: Can't open input file %s: %s.\n",
1275 if( outStr !=
NULL) fclose ( outStr );
1282 panic(
"compress: bad srcMode");
1287fprintf ( stderr,
" %s: ",
inName);
1326 panic(
"uncompress: bad modes\n");
1352fprintf ( stderr,
"%s: There are no files matching `%s'.\n",
1358fprintf ( stderr,
"%s: Can't open input file %s: %s.\n",
1367 "%s: Input file %s is a directory.\n",
1375fprintf ( stderr,
"%s: Input file %s is not a normal file.\n",
1383 "%s: Can't guess original name for %s -- using %s\n",
1391fprintf ( stderr,
"%s: Output file %s already exists.\n",
1399fprintf ( stderr,
"%s: Input file %s has %d other link%s.\n",
1416 if( isatty ( fileno ( stdin ) ) ) {
1418 "%s: I won't read compressed data from a terminal.\n",
1420fprintf ( stderr,
"%s: For help, type: `%s --help'.\n",
1428inStr = fopen (
inName,
"rb");
1430 if( inStr ==
NULL) {
1431fprintf ( stderr,
"%s: Can't open input file %s:%s.\n",
1433 if( inStr !=
NULL) fclose ( inStr );
1440inStr = fopen (
inName,
"rb");
1442 if( outStr ==
NULL) {
1443fprintf ( stderr,
"%s: Can't create output file %s: %s.\n",
1445 if( inStr !=
NULL) fclose ( inStr );
1449 if( inStr ==
NULL) {
1450fprintf ( stderr,
"%s: Can't open input file %s: %s.\n",
1452 if( outStr !=
NULL) fclose ( outStr );
1459 panic(
"uncompress: bad srcMode");
1464fprintf ( stderr,
" %s: ",
inName);
1476 if( magicNumberOK ) {
1495 if( magicNumberOK ) {
1497fprintf ( stderr,
"done\n");
1501fprintf ( stderr,
"not a bzip2 file.\n");
else 1503 "%s: %s is not a bzip2 file.\n",
1521 panic(
"testf: bad modes\n");
1532fprintf ( stderr,
"%s: There are no files matching `%s'.\n",
1538fprintf ( stderr,
"%s: Can't open input %s: %s.\n",
1547 "%s: Input file %s is a directory.\n",
1557 if( isatty ( fileno ( stdin ) ) ) {
1559 "%s: I won't read compressed data from a terminal.\n",
1561fprintf ( stderr,
"%s: For help, type: `%s --help'.\n",
1570inStr = fopen (
inName,
"rb");
1571 if( inStr ==
NULL) {
1572fprintf ( stderr,
"%s: Can't open input file %s:%s.\n",
1580 panic(
"testf: bad srcMode");
1585fprintf ( stderr,
" %s: ",
inName);
1594 if(allOK &&
verbosity>= 1) fprintf ( stderr,
"ok\n");
1605 "bzip2, a block-sorting file compressor. " 1608 " Copyright (C) 1996-2019 by Julian Seward.\n" 1610 " This program is free software; you can redistribute it and/or modify\n" 1611 " it under the terms set out in the LICENSE file, which is included\n" 1612 " in the bzip2 source distribution.\n" 1614 " This program is distributed in the hope that it will be useful,\n" 1615 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 1616 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 1617 " LICENSE file for more details.\n" 1630 "bzip2, a block-sorting file compressor. " 1632 "\n usage: %s [flags and input files in any order]\n" 1634 " -h --help print this message\n" 1635 " -d --decompress force decompression\n" 1636 " -z --compress force compression\n" 1637 " -k --keep keep (don't delete) input files\n" 1638 " -f --force overwrite existing output files\n" 1639 " -t --test test compressed file integrity\n" 1640 " -c --stdout output to standard out\n" 1641 " -q --quiet suppress noncritical error messages\n" 1642 " -v --verbose be verbose (a 2nd -v gives more)\n" 1643 " -L --license display software version & license\n" 1644 " -V --version display software version & license\n" 1645 " -s --small use less memory (at most 2500k)\n" 1646 " -1 .. -9 set block size to 100k .. 900k\n" 1647 " --fast alias for -1\n" 1648 " --best alias for -9\n" 1650 " If invoked as `bzip2', default action is to compress.\n" 1651 " as `bunzip2', default action is to decompress.\n" 1652 " as `bzcat', default action is to decompress to stdout.\n" 1654 " If no file names are given, bzip2 compresses or decompresses\n" 1655 " from standard input to standard output. You can combine\n" 1656 " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n" 1674 "%s: %s is redundant in versions 0.9.5 and above\n",
1731 if(root ==
NULL) {
1752envbase = getenv(varName);
1753 if(envbase !=
NULL) {
1757 if(p[
i] == 0)
break;
1764 for(j = 0; j < k; j++)
tmpName[j] = p[j];
1774 #define ISFLAG(s) (strcmp(aa->name, (s))==0) 1785 if(
sizeof(
Int32) != 4 ||
sizeof(
UInt32) != 4 ||
1786 sizeof(
Int16) != 2 ||
sizeof(
UInt16) != 2 ||
1787 sizeof(
Char) != 1 ||
sizeof(
UChar) != 1)
1830 for(
i= 1;
i<= argc-1;
i++)
1838 for(aa = argList; aa !=
NULL; aa = aa->link) {
1840 if(aa->name[0] ==
'-'&&
decode)
continue;
1856 if( (strstr (
progName,
"unzip") != 0) ||
1857(strstr (
progName,
"UNZIP") != 0) )
1860 if( (strstr (
progName,
"z2cat") != 0) ||
1861(strstr (
progName,
"Z2CAT") != 0) ||
1862(strstr (
progName,
"zcat") != 0) ||
1863(strstr (
progName,
"ZCAT") != 0) ) {
1870 for(aa = argList; aa !=
NULL; aa = aa->link) {
1871 if(
ISFLAG(
"--"))
break;
1872 if(aa->name[0] ==
'-'&& aa->name[1] !=
'-') {
1873 for(j = 1; aa->name[j] !=
'\0'; j++) {
1874 switch(aa->name[j]) {
1893 case 'L':
license();
break;
1898 default: fprintf ( stderr,
"%s: Bad flag `%s'\n",
1909 for(aa = argList; aa !=
NULL; aa = aa->link) {
1910 if(
ISFLAG(
"--"))
break;
1929 if(
strncmp( aa->name,
"--", 2) == 0) {
1930fprintf ( stderr,
"%s: Bad flag `%s'\n",
progName, aa->name );
1941fprintf ( stderr,
"%s: -c and -t cannot be used together.\n",
1964 for(aa = argList; aa !=
NULL; aa = aa->link) {
1966 if(aa->name[0] ==
'-'&&
decode)
continue;
1980 for(aa = argList; aa !=
NULL; aa = aa->link) {
1982 if(aa->name[0] ==
'-'&&
decode)
continue;
1999 for(aa = argList; aa !=
NULL; aa = aa->link) {
2001 if(aa->name[0] ==
'-'&&
decode)
continue;
2010 "You can use the `bzip2recover' program to attempt to recover\n" 2011 "data from undamaged sections of corrupted files.\n\n" 2023 while(aa !=
NULL) {
2024 Cell* aa2 = aa->link;
2025 if(aa->name !=
NULL)
free(aa->name);
static void uInt64_from_UInt32s(UInt64 *n, UInt32 lo32, UInt32 hi32)
static void outOfMemory(void)
static Bool uInt64_isZero(UInt64 *n)
static void applySavedFileAttrToOutputFile(IntNative fd)
static void cadvise(void)
#define APPEND_FILESPEC(root, name)
static void addFlagsFromEnvVar(Cell **argList, Char *varName)
static void setExit(Int32 v)
static Bool testStream(FILE *zStream)
static void uInt64_toAscii(char *outbuf, UInt64 *n)
static double uInt64_to_double(UInt64 *n)
static void ioError(void)
FILE * outputHandleJustInCase
#define SET_BINARY_MODE(fd)
static Bool notAStandardFile(Char *name)
static void uncompress(Char *name)
#define ERROR_IF_NOT_ZERO(i)
static void * myMalloc(Int32)
static void mySignalCatcher(IntNative n)
static void cleanUpAndFail(Int32)
static void license(void)
static void compress(Char *name)
IntNative main(IntNative argc, Char *argv[])
static void testf(Char *name)
static Int32 countHardLinks(Char *name)
static struct stat fileMetaInfo
static void compressedStreamEOF(void)
#define APPEND_FLAG(root, name)
static Bool uncompressStream(FILE *zStream, FILE *stream)
static void compressStream(FILE *stream, FILE *zStream)
static Bool hasSuffix(Char *s, const Char *suffix)
static void applySavedTimeInfoToOutputFile(Char *dstName)
static Int32 uInt64_qrm10(UInt64 *n)
#define BZ_N_SUFFIX_PAIRS
static void redundant(Char *flag)
static void usage(Char *fullProgName)
static Bool mapSuffix(Char *name, const Char *oldSuffix, const Char *newSuffix)
static void copyFileName(Char *, Char *)
Bool deleteOutputOnInterrupt
static Cell * mkCell(void)
static void mySIGSEGVorSIGBUScatcher(IntNative n)
static void panic(const Char *)
static Cell * snocString(Cell *root, Char *name)
static void showFileNames(void)
static Bool containsDubiousChars(Char *name)
Char progNameReally[1034]
static void configError(void)
static Bool myfeof(FILE *f)
static FILE * fopen_output_safely(Char *name, const char *mode)
const Char * unzSuffix[4]
static void saveInputFileMetaInfo(Char *srcName)
static void crcError(void)
static Bool fileExists(Char *name)
void BZ2_bzReadGetUnused(int *bzerror, BZFILE *b, void **unused, int *nUnused)
const char * BZ2_bzlibVersion(void)
void BZ2_bzWrite(int *bzerror, BZFILE *b, void *buf, int len)
#define BZ_DATA_ERROR_MAGIC
int BZ2_bzRead(int *bzerror, BZFILE *b, void *buf, int len)
BZFILE * BZ2_bzReadOpen(int *bzerror, FILE *f, int verbosity, int small, void *unused, int nUnused)
BZFILE * BZ2_bzWriteOpen(int *bzerror, FILE *f, int blockSize100k, int verbosity, int workFactor)
#define BZ_UNEXPECTED_EOF
void BZ2_bzReadClose(int *bzerror, BZFILE *b)
void BZ2_bzWriteClose64(int *bzerror, BZFILE *b, int abandon, unsigned int *nbytes_in_lo32, unsigned int *nbytes_in_hi32, unsigned int *nbytes_out_lo32, unsigned int *nbytes_out_hi32)
static void DLIST_NAME() remove(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
NCBI_DEPRECATED_CLASS NCBI_XCGI_EXPORT EUrlEncode decode
char Char
Alias for char.
static const CS_INT unused
int strncmp(const char *str1, const char *str2, size_t count)
int strcmp(const char *str1, const char *str2)
uchar outbuf[(1000000+1000000)]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4