├── ChangeLog ├── compat ├── Makefile.am └── jansson │ ├── util.h │ ├── Makefile.am │ ├── utf.h │ ├── strbuffer.h │ ├── LICENSE │ ├── jansson_private.h │ ├── config.h │ ├── strbuffer.c │ ├── utf.c │ ├── jansson.h │ ├── hashtable.h │ ├── hashtable.c │ ├── dump.c │ ├── value.c │ └── load.c ├── LICENSE ├── AUTHORS ├── autogen.sh ├── example-cfg.json ├── .gitignore ├── compat.h ├── Makefile.am ├── nomacro.pl ├── gc3355-commands.h ├── README ├── README.md ├── configure.ac ├── minerd.1 ├── elist.h ├── NEWS ├── miner.h ├── sha2.c ├── COPYING └── scrypt-x86.S /ChangeLog: -------------------------------------------------------------------------------- 1 | See git repository ('git log') for full changelog. 2 | -------------------------------------------------------------------------------- /compat/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | if WANT_JANSSON 3 | SUBDIRS = jansson 4 | else 5 | SUBDIRS = 6 | endif 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | cpuminer is available under the terms of the GNU Public License version 2. 2 | 3 | See COPYING for details. 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Jeff Garzik 2 | 3 | ArtForz 4 | 5 | pooler 6 | 7 | 8 | faster -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # You need autoconf 2.5x, preferably 2.57 or later 4 | # You need automake 1.7 or later. 1.6 might work. 5 | 6 | set -e 7 | 8 | aclocal 9 | autoheader 10 | automake --gnu --add-missing --copy 11 | autoconf 12 | 13 | -------------------------------------------------------------------------------- /example-cfg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment1" : "Any long-format command line argument ", 3 | "_comment2" : "may be used in this JSON configuration file", 4 | 5 | "url" : "http://127.0.0.1:9332/", 6 | "user" : "rpcuser", 7 | "pass" : "rpcpass", 8 | 9 | "algo" : "scrypt", 10 | "threads" : "4", 11 | 12 | "quiet" : true 13 | } 14 | -------------------------------------------------------------------------------- /compat/jansson/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef UTIL_H 9 | #define UTIL_H 10 | 11 | #define max(a, b) ((a) > (b) ? (a) : (b)) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /compat/jansson/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_LIBRARIES = libjansson.a 3 | 4 | libjansson_a_SOURCES = \ 5 | config.h \ 6 | dump.c \ 7 | hashtable.c \ 8 | hashtable.h \ 9 | jansson.h \ 10 | jansson_private.h \ 11 | load.c \ 12 | strbuffer.c \ 13 | strbuffer.h \ 14 | utf.c \ 15 | utf.h \ 16 | util.h \ 17 | value.c 18 | 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | minerd 3 | minerd.exe 4 | *.o 5 | 6 | autom4te.cache 7 | .deps 8 | 9 | Makefile 10 | Makefile.in 11 | INSTALL 12 | aclocal.m4 13 | configure 14 | configure.lineno 15 | depcomp 16 | missing 17 | install-sh 18 | stamp-h1 19 | cpuminer-config.h* 20 | compile 21 | config.log 22 | config.status 23 | config.status.lineno 24 | config.guess 25 | config.sub 26 | 27 | mingw32-config.cache 28 | 29 | -------------------------------------------------------------------------------- /compat.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMPAT_H__ 2 | #define __COMPAT_H__ 3 | 4 | #ifdef WIN32 5 | 6 | #include 7 | 8 | #define sleep(secs) Sleep((secs) * 1000) 9 | 10 | enum { 11 | PRIO_PROCESS = 0, 12 | }; 13 | 14 | static inline int setpriority(int which, int who, int prio) 15 | { 16 | return -!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); 17 | } 18 | 19 | #endif /* WIN32 */ 20 | 21 | #endif /* __COMPAT_H__ */ 22 | -------------------------------------------------------------------------------- /compat/jansson/utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef UTF_H 9 | #define UTF_H 10 | 11 | #include 12 | 13 | #ifdef HAVE_INTTYPES_H 14 | /* inttypes.h includes stdint.h in a standard environment, so there's 15 | no need to include stdint.h separately. If inttypes.h doesn't define 16 | int32_t, it's defined in config.h. */ 17 | #include 18 | #endif 19 | 20 | int utf8_encode(int codepoint, char *buffer, int *size); 21 | 22 | int utf8_check_first(char byte); 23 | int utf8_check_full(const char *buffer, int size, int32_t *codepoint); 24 | const char *utf8_iterate(const char *buffer, int32_t *codepoint); 25 | 26 | int utf8_check_string(const char *string, int length); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | if WANT_JANSSON 3 | JANSSON_CPPFLAGS= -I$(top_srcdir)/compat/jansson 4 | else 5 | JANSSON_CPPFLAGS= 6 | endif 7 | 8 | EXTRA_DIST = example-cfg.json nomacro.pl 9 | 10 | SUBDIRS = compat 11 | 12 | minerd_CPPFLAGS = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_CPPFLAGS) 13 | 14 | bin_PROGRAMS = minerd 15 | 16 | dist_man_MANS = minerd.1 17 | 18 | minerd_SOURCES = elist.h miner.h compat.h \ 19 | cpu-miner.c util.c \ 20 | gc3355.h \ 21 | sha2.c scrypt.c 22 | if ARCH_x86 23 | minerd_SOURCES += sha2-x86.S scrypt-x86.S 24 | endif 25 | if ARCH_x86_64 26 | minerd_SOURCES += sha2-x64.S scrypt-x64.S 27 | endif 28 | if ARCH_ARM 29 | minerd_SOURCES += sha2-arm.S scrypt-arm.S 30 | endif 31 | minerd_LDFLAGS = $(PTHREAD_FLAGS) 32 | minerd_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @WS2_LIBS@ @NCURSES_LIBS@ @PDCURSES_LIBS@ @UDEV_LIBS@ @SETUPAPI_LIBS@ 33 | minerd_CPPFLAGS += @LIBCURL_CPPFLAGS@ 34 | -------------------------------------------------------------------------------- /compat/jansson/strbuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef STRBUFFER_H 9 | #define STRBUFFER_H 10 | 11 | typedef struct { 12 | char *value; 13 | int length; /* bytes used */ 14 | int size; /* bytes allocated */ 15 | } strbuffer_t; 16 | 17 | int strbuffer_init(strbuffer_t *strbuff); 18 | void strbuffer_close(strbuffer_t *strbuff); 19 | 20 | void strbuffer_clear(strbuffer_t *strbuff); 21 | 22 | const char *strbuffer_value(const strbuffer_t *strbuff); 23 | char *strbuffer_steal_value(strbuffer_t *strbuff); 24 | 25 | int strbuffer_append(strbuffer_t *strbuff, const char *string); 26 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte); 27 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size); 28 | 29 | char strbuffer_pop(strbuffer_t *strbuff); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /compat/jansson/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, 2010 Petri Lehtinen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /nomacro.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Copyright 2012 pooler@litecoinpool.org 3 | # 4 | # This program is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License as published by the Free 6 | # Software Foundation; either version 2 of the License, or (at your option) 7 | # any later version. See COPYING for more details. 8 | # 9 | # nomacro.pl - convert assembler macros to C preprocessor macros. 10 | 11 | use strict; 12 | 13 | foreach my $f (<*.S>) { 14 | rename $f, "$f.orig"; 15 | open FIN, "$f.orig"; 16 | open FOUT, ">$f"; 17 | my $inmacro = 0; 18 | my %macros = (); 19 | while () { 20 | if (m/^\.macro\s+([_0-9A-Z]+)(?:\s*)(.*)$/i) { 21 | print FOUT "#define $1($2) \\\n"; 22 | $macros{$1} = 1; 23 | $inmacro = 1; 24 | next; 25 | } 26 | if (m/^\.endm/) { 27 | print FOUT "\n"; 28 | $inmacro = 0; 29 | next; 30 | } 31 | for my $m (keys %macros) { 32 | s/^([ \t]*)($m)(?:[ \t]+([^#\n]*))?([;\n])/\1\2(\3)\4/; 33 | } 34 | if ($inmacro) { 35 | if (m/^\s*#if/) { 36 | $_ = while (!m/^\s*#endif/); 37 | next; 38 | } 39 | next if (m/^\s*$/); 40 | s/\\//g; 41 | s/$/; \\/; 42 | } 43 | print FOUT; 44 | } 45 | close FOUT; 46 | close FIN; 47 | } 48 | -------------------------------------------------------------------------------- /gc3355-commands.h: -------------------------------------------------------------------------------- 1 | /* reset gcp */ 2 | static const unsigned char *gcp_cmd_reset[] = { 3 | (unsigned char[]) {0x10, 0x55, 0xaa, 0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, 4 | NULL 5 | }; 6 | 7 | /* commands for single LTC mode */ 8 | static const unsigned char *single_cmd_init[] = { 9 | /* set # of chips to 5 */ 10 | (unsigned char[]) {0x10, 0x55, 0xaa, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, 11 | /* disable btc cores */ 12 | (unsigned char[]) {0x18, 0x55, 0xaa, 0xef, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 13 | /* enable ltc */ 14 | (unsigned char[]) {0x08, 0x55, 0xaa, 0xef, 0x30, 0x20, 0x00, 0x00, 0x00}, 15 | NULL 16 | }; 17 | 18 | static const unsigned char *single_cmd_reset[] = { 19 | /* reset ltc calculation unit */ 20 | (unsigned char[]) {0x08, 0x55, 0xaa, 0x1f, 0x28, 0x16, 0x00, 0x00, 0x00}, 21 | /* clear reset */ 22 | (unsigned char[]) {0x08, 0x55, 0xaa, 0x1f, 0x28, 0x17, 0x00, 0x00, 0x00}, 23 | NULL 24 | }; 25 | 26 | static const unsigned char *firmware_request_cmd[] = { 27 | (unsigned char[]) {0x10, 0x55, 0xaa, 0xc0, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, 28 | NULL 29 | }; -------------------------------------------------------------------------------- /compat/jansson/jansson_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef JANSSON_PRIVATE_H 9 | #define JANSSON_PRIVATE_H 10 | 11 | #include "jansson.h" 12 | #include "hashtable.h" 13 | 14 | #define container_of(ptr_, type_, member_) \ 15 | ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) 16 | 17 | typedef struct { 18 | json_t json; 19 | hashtable_t hashtable; 20 | unsigned long serial; 21 | int visited; 22 | } json_object_t; 23 | 24 | typedef struct { 25 | json_t json; 26 | unsigned int size; 27 | unsigned int entries; 28 | json_t **table; 29 | int visited; 30 | } json_array_t; 31 | 32 | typedef struct { 33 | json_t json; 34 | char *value; 35 | } json_string_t; 36 | 37 | typedef struct { 38 | json_t json; 39 | double value; 40 | } json_real_t; 41 | 42 | typedef struct { 43 | json_t json; 44 | int value; 45 | } json_integer_t; 46 | 47 | #define json_to_object(json_) container_of(json_, json_object_t, json) 48 | #define json_to_array(json_) container_of(json_, json_array_t, json) 49 | #define json_to_string(json_) container_of(json_, json_string_t, json) 50 | #define json_to_real(json_) container_of(json_, json_real_t, json) 51 | #define json_to_integer(json_) container_of(json_, json_integer_t, json) 52 | 53 | typedef struct { 54 | unsigned long serial; 55 | char key[]; 56 | } object_key_t; 57 | 58 | const object_key_t *jsonp_object_iter_fullkey(void *iter); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /compat/jansson/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the header file. */ 5 | #define HAVE_DLFCN_H 1 6 | 7 | /* Define to 1 if you have the header file. */ 8 | #define HAVE_INTTYPES_H 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_MEMORY_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_STDINT_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_STDLIB_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #define HAVE_STRINGS_H 1 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_STRING_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_SYS_STAT_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_SYS_TYPES_H 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_UNISTD_H 1 33 | 34 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 35 | */ 36 | #define LT_OBJDIR ".libs/" 37 | 38 | /* Name of package */ 39 | #define PACKAGE "jansson" 40 | 41 | /* Define to the address where bug reports for this package should be sent. */ 42 | #define PACKAGE_BUGREPORT "petri@digip.org" 43 | 44 | /* Define to the full name of this package. */ 45 | #define PACKAGE_NAME "jansson" 46 | 47 | /* Define to the full name and version of this package. */ 48 | #define PACKAGE_STRING "jansson 1.3" 49 | 50 | /* Define to the one symbol short name of this package. */ 51 | #define PACKAGE_TARNAME "jansson" 52 | 53 | /* Define to the home page for this package. */ 54 | #define PACKAGE_URL "" 55 | 56 | /* Define to the version of this package. */ 57 | #define PACKAGE_VERSION "1.3" 58 | 59 | /* Define to 1 if you have the ANSI C header files. */ 60 | #define STDC_HEADERS 1 61 | 62 | /* Version number of package */ 63 | #define VERSION "1.3" 64 | 65 | /* Define to `__inline__' or `__inline' if that's what the C compiler 66 | calls it, or to nothing if 'inline' is not supported under any name. */ 67 | #ifndef __cplusplus 68 | /* #undef inline */ 69 | #endif 70 | 71 | /* Define to the type of a signed integer type of width exactly 32 bits if 72 | such a type exists and the standard includes do not define it. */ 73 | /* #undef int32_t */ 74 | -------------------------------------------------------------------------------- /compat/jansson/strbuffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include "strbuffer.h" 12 | #include "util.h" 13 | 14 | #define STRBUFFER_MIN_SIZE 16 15 | #define STRBUFFER_FACTOR 2 16 | 17 | int strbuffer_init(strbuffer_t *strbuff) 18 | { 19 | strbuff->size = STRBUFFER_MIN_SIZE; 20 | strbuff->length = 0; 21 | 22 | strbuff->value = malloc(strbuff->size); 23 | if(!strbuff->value) 24 | return -1; 25 | 26 | /* initialize to empty */ 27 | strbuff->value[0] = '\0'; 28 | return 0; 29 | } 30 | 31 | void strbuffer_close(strbuffer_t *strbuff) 32 | { 33 | free(strbuff->value); 34 | strbuff->size = 0; 35 | strbuff->length = 0; 36 | strbuff->value = NULL; 37 | } 38 | 39 | void strbuffer_clear(strbuffer_t *strbuff) 40 | { 41 | strbuff->length = 0; 42 | strbuff->value[0] = '\0'; 43 | } 44 | 45 | const char *strbuffer_value(const strbuffer_t *strbuff) 46 | { 47 | return strbuff->value; 48 | } 49 | 50 | char *strbuffer_steal_value(strbuffer_t *strbuff) 51 | { 52 | char *result = strbuff->value; 53 | strbuffer_init(strbuff); 54 | return result; 55 | } 56 | 57 | int strbuffer_append(strbuffer_t *strbuff, const char *string) 58 | { 59 | return strbuffer_append_bytes(strbuff, string, strlen(string)); 60 | } 61 | 62 | int strbuffer_append_byte(strbuffer_t *strbuff, char byte) 63 | { 64 | return strbuffer_append_bytes(strbuff, &byte, 1); 65 | } 66 | 67 | int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size) 68 | { 69 | if(strbuff->length + size >= strbuff->size) 70 | { 71 | strbuff->size = max(strbuff->size * STRBUFFER_FACTOR, 72 | strbuff->length + size + 1); 73 | 74 | strbuff->value = realloc(strbuff->value, strbuff->size); 75 | if(!strbuff->value) 76 | return -1; 77 | } 78 | 79 | memcpy(strbuff->value + strbuff->length, data, size); 80 | strbuff->length += size; 81 | strbuff->value[strbuff->length] = '\0'; 82 | 83 | return 0; 84 | } 85 | 86 | char strbuffer_pop(strbuffer_t *strbuff) 87 | { 88 | if(strbuff->length > 0) { 89 | char c = strbuff->value[--strbuff->length]; 90 | strbuff->value[strbuff->length] = '\0'; 91 | return c; 92 | } 93 | else 94 | return '\0'; 95 | } 96 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is a multi-threaded CPU miner for Litecoin and Bitcoin, 2 | fork of Jeff Garzik's reference cpuminer. 3 | 4 | License: GPLv2. See COPYING for details. 5 | 6 | Downloads: https://sourceforge.net/projects/cpuminer/files/ 7 | Git tree: https://github.com/pooler/cpuminer 8 | 9 | Dependencies: 10 | libcurl http://curl.haxx.se/libcurl/ 11 | jansson http://www.digip.org/jansson/ 12 | (jansson is included in-tree) 13 | 14 | Basic *nix build instructions: 15 | ./autogen.sh # only needed if building from git repo 16 | ./nomacro.pl # only needed if building on Mac OS X or with Clang 17 | ./configure CFLAGS="-O3" 18 | make 19 | 20 | Notes for AIX users: 21 | * To build a 64-bit binary, export OBJECT_MODE=64 22 | * GNU-style long options are not supported, but are accessible 23 | via configuration file 24 | 25 | Basic Windows build instructions, using MinGW: 26 | Install MinGW and the MSYS Developer Tool Kit (http://www.mingw.org/) 27 | * Make sure you have mstcpip.h in MinGW\include 28 | If using MinGW-w64, install pthreads-w64 29 | Install libcurl devel (http://curl.haxx.se/download.html) 30 | * Make sure you have libcurl.m4 in MinGW\share\aclocal 31 | * Make sure you have curl-config in MinGW\bin 32 | In the MSYS shell, run: 33 | ./autogen.sh # only needed if building from git repo 34 | LIBCURL="-lcurldll" ./configure CFLAGS="-O3" 35 | make 36 | 37 | Architecture-specific notes: 38 | ARM: No runtime CPU detection. The miner can take advantage 39 | of some instructions specific to ARMv5E and later processors, 40 | but the decision whether to use them is made at compile time, 41 | based on compiler-defined macros. 42 | To use NEON instructions, add "-mfpu=neon" to CFLAGS. 43 | x86: The miner checks for SSE2 instructions support at runtime, 44 | and uses them if they are available. 45 | x86-64: The miner can take advantage of AVX, AVX2 and XOP instructions, 46 | but only if both the CPU and the operating system support them. 47 | * Linux supports AVX starting from kernel version 2.6.30. 48 | * FreeBSD supports AVX starting with 9.1-RELEASE. 49 | * Mac OS X added AVX support in the 10.6.8 update. 50 | * Windows supports AVX starting from Windows 7 SP1 and 51 | Windows Server 2008 R2 SP1. 52 | The configure script outputs a warning if the assembler 53 | doesn't support some instruction sets. In that case, the miner 54 | can still be built, but unavailable optimizations are left off. 55 | 56 | Usage instructions: Run "minerd --help" to see options. 57 | 58 | Connecting through a proxy: Use the --proxy option. 59 | To use a SOCKS proxy, add a socks4:// or socks5:// prefix to the proxy host. 60 | Protocols socks4a and socks5h, allowing remote name resolving, are also 61 | available since libcurl 7.18.0. 62 | If no protocol is specified, the proxy is assumed to be a HTTP proxy. 63 | When the --proxy option is not used, the program honors the http_proxy 64 | and all_proxy environment variables. 65 | 66 | Also many issues and FAQs are covered in the forum thread 67 | dedicated to this program, 68 | https://bitcointalk.org/index.php?topic=55038.0 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cpuminer-gc3355 2 | ============== 3 | 4 | CPUMiner with GridSeed GC3355 support 5 | 6 | How to compile from git (Debian-based): 7 | 8 | ``` 9 | apt-get update 10 | apt-get install -y build-essential libtool libcurl4-openssl-dev libjansson-dev libudev-dev libncurses5-dev autoconf automake 11 | git clone https://github.com/siklon/cpuminer-gc3355 12 | cd cpuminer-gc3355 13 | ./autogen.sh 14 | ./configure CFLAGS="-O3" 15 | make 16 | ``` 17 | 18 | Failover pool strategy is supported (see config). The first pool specified is the main pool. 19 | 20 | GC3355-specific options: 21 | 22 | ``` 23 | --gc3355=DEV0,DEV1,...,DEVn enable GC3355 chip mining mode (default: no) 24 | --gc3355-detect automatically detect GC3355 miners (default: no) 25 | --freq=FREQUENCY set GC3355 core frequency in NONE dual mode (default: 600) 26 | --gc3355-freq=DEV0:F0,DEV1:F1,...,DEVn:Fn individual frequency setting 27 | --gc3355-freq=DEV0:F0:CHIP0,...,DEVn:Fn:CHIPn individual per chip frequency setting 28 | --gc3355-autotune auto overclocking each GC3355 chip (default: no) 29 | --gc3355-timeout=N max. time in seconds after no share is submitted before restarting GC3355 (default: never) 30 | ``` 31 | 32 | There are multiple ways to set the frequency. 33 | 34 | By device name: 35 | 36 | Linux: `--gc3355-freq=/dev/ttyACM0:850` Windows: `--gc3355-freq=\\.\COM3:850` 37 | 38 | By serial string: 39 | 40 | `--gc3355-freq=8D751F965355:850` 41 | 42 | If you cannot find any /dev/ttyUSB or /dev/ttyACM, it related to running cgminer, this can easily be fixed by rebooting the system. 43 | 44 | You do not need the set the # of chips for USB Miner or G-Blade, it is detected automatically 45 | 46 | For the G-Blade, no additional command line parameters are needed, it will be detected automatically. 47 | You can only set the frequency of chip_id 0-7, each chip_id represents 5 chips in this case. 48 | You cannot set the frequency of an individual chip on your G-Blade. 49 | 50 | Config 51 | ============== 52 | 53 | Use JSON config with `-c name_of_config` 54 | 55 | Example JSON Config: 56 | 57 | ``` 58 | { 59 | "gc3355-detect" : true, 60 | "gc3355-freq" : [ 61 | "\\\\.\\COM3:850", "\\\\.\\COM3:875:0", "\\\\.\\COM3:900:3", 62 | "\\\\.\\COM4:900", 63 | "\\\\.\\COM5:875" 64 | ], 65 | "gc3355-autotune" : true, 66 | "pools" : [ 67 | { 68 | "url" : "stratum+tcp://eu.wafflepool.com:3333", 69 | "user" : "1AMsjqzXQpRunxUmtn3xzQ5cMdhV7fmet2", 70 | "pass" : "x" 71 | }, 72 | { 73 | "url" : "stratum+tcp://doge.ghash.io:3333", 74 | "user" : "user", 75 | "pass" : "x" 76 | } 77 | ], 78 | "freq" : "850", 79 | "debug" : true 80 | } 81 | ``` 82 | 83 | API 84 | ============== 85 | The API is accessible on port 4028 (by default), to change the port pass --api-port=PORT 86 | 87 | One GET command is currently supported: 88 | ``` 89 | {"get":"stats"}\n 90 | ``` 91 | This will output a JSON encoded array with mining stats for each GC3355 chip. 92 | 93 | One SET command is currently supported: 94 | ``` 95 | {"set":"frequency", "devices":{"ttyACM0":{"chips":[825,850,875,900,850]}}}\n 96 | ``` 97 | This will set the frequency on the fly of the GC3355 chips to 825MHz (chip0), 850MHz (chip1), 875MHz (chip2), 900MHz (chip3), 850MHz (chip4) 98 | 99 | You can specify multiple devices, but the length of the chips array must be equal to the number of chips on the GC3355 miners, Blades have 40 chips but you can only address chip0-7 (clusters of 5 chips), so the max is 8. 100 | 101 | To translate the JSON keys, please refer to cpu-miner.c:66 102 | 103 | Do not forget the newline (\n), it is used to tell the API to stop reading and execute the command! 104 | 105 | Windows is not supported. 106 | 107 | Binaries 108 | ============== 109 | 110 | Windows: https://www.dropbox.com/s/ttqa9p851siz8oi/minerd-gc3355.zip 111 | 112 | Raspberry PI: https://www.dropbox.com/s/xc3lvysi8vtrt00/minerd-gc3355 113 | 114 | Support 115 | ============== 116 | 117 | `BTC: 1AMsjqzXQpRunxUmtn3xzQ5cMdhV7fmet2` 118 | 119 | 120 | `LTC: Lc75scqhMCkpMhC3aYGPVB4BEAzHvvz2rm` 121 | 122 | 123 | `DOGE: DFZ3rxAUgFspMfpZbqMzgRFFQKiT695HCo` -------------------------------------------------------------------------------- /compat/jansson/utf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include 9 | #include "utf.h" 10 | 11 | int utf8_encode(int32_t codepoint, char *buffer, int *size) 12 | { 13 | if(codepoint < 0) 14 | return -1; 15 | else if(codepoint < 0x80) 16 | { 17 | buffer[0] = (char)codepoint; 18 | *size = 1; 19 | } 20 | else if(codepoint < 0x800) 21 | { 22 | buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6); 23 | buffer[1] = 0x80 + ((codepoint & 0x03F)); 24 | *size = 2; 25 | } 26 | else if(codepoint < 0x10000) 27 | { 28 | buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12); 29 | buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6); 30 | buffer[2] = 0x80 + ((codepoint & 0x003F)); 31 | *size = 3; 32 | } 33 | else if(codepoint <= 0x10FFFF) 34 | { 35 | buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18); 36 | buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12); 37 | buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6); 38 | buffer[3] = 0x80 + ((codepoint & 0x00003F)); 39 | *size = 4; 40 | } 41 | else 42 | return -1; 43 | 44 | return 0; 45 | } 46 | 47 | int utf8_check_first(char byte) 48 | { 49 | unsigned char u = (unsigned char)byte; 50 | 51 | if(u < 0x80) 52 | return 1; 53 | 54 | if(0x80 <= u && u <= 0xBF) { 55 | /* second, third or fourth byte of a multi-byte 56 | sequence, i.e. a "continuation byte" */ 57 | return 0; 58 | } 59 | else if(u == 0xC0 || u == 0xC1) { 60 | /* overlong encoding of an ASCII byte */ 61 | return 0; 62 | } 63 | else if(0xC2 <= u && u <= 0xDF) { 64 | /* 2-byte sequence */ 65 | return 2; 66 | } 67 | 68 | else if(0xE0 <= u && u <= 0xEF) { 69 | /* 3-byte sequence */ 70 | return 3; 71 | } 72 | else if(0xF0 <= u && u <= 0xF4) { 73 | /* 4-byte sequence */ 74 | return 4; 75 | } 76 | else { /* u >= 0xF5 */ 77 | /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid 78 | UTF-8 */ 79 | return 0; 80 | } 81 | } 82 | 83 | int utf8_check_full(const char *buffer, int size, int32_t *codepoint) 84 | { 85 | int i; 86 | int32_t value = 0; 87 | unsigned char u = (unsigned char)buffer[0]; 88 | 89 | if(size == 2) 90 | { 91 | value = u & 0x1F; 92 | } 93 | else if(size == 3) 94 | { 95 | value = u & 0xF; 96 | } 97 | else if(size == 4) 98 | { 99 | value = u & 0x7; 100 | } 101 | else 102 | return 0; 103 | 104 | for(i = 1; i < size; i++) 105 | { 106 | u = (unsigned char)buffer[i]; 107 | 108 | if(u < 0x80 || u > 0xBF) { 109 | /* not a continuation byte */ 110 | return 0; 111 | } 112 | 113 | value = (value << 6) + (u & 0x3F); 114 | } 115 | 116 | if(value > 0x10FFFF) { 117 | /* not in Unicode range */ 118 | return 0; 119 | } 120 | 121 | else if(0xD800 <= value && value <= 0xDFFF) { 122 | /* invalid code point (UTF-16 surrogate halves) */ 123 | return 0; 124 | } 125 | 126 | else if((size == 2 && value < 0x80) || 127 | (size == 3 && value < 0x800) || 128 | (size == 4 && value < 0x10000)) { 129 | /* overlong encoding */ 130 | return 0; 131 | } 132 | 133 | if(codepoint) 134 | *codepoint = value; 135 | 136 | return 1; 137 | } 138 | 139 | const char *utf8_iterate(const char *buffer, int32_t *codepoint) 140 | { 141 | int count; 142 | int32_t value; 143 | 144 | if(!*buffer) 145 | return buffer; 146 | 147 | count = utf8_check_first(buffer[0]); 148 | if(count <= 0) 149 | return NULL; 150 | 151 | if(count == 1) 152 | value = (unsigned char)buffer[0]; 153 | else 154 | { 155 | if(!utf8_check_full(buffer, count, &value)) 156 | return NULL; 157 | } 158 | 159 | if(codepoint) 160 | *codepoint = value; 161 | 162 | return buffer + count; 163 | } 164 | 165 | int utf8_check_string(const char *string, int length) 166 | { 167 | int i; 168 | 169 | if(length == -1) 170 | length = strlen(string); 171 | 172 | for(i = 0; i < length; i++) 173 | { 174 | int count = utf8_check_first(string[i]); 175 | if(count == 0) 176 | return 0; 177 | else if(count > 1) 178 | { 179 | if(i + count > length) 180 | return 0; 181 | 182 | if(!utf8_check_full(&string[i], count, NULL)) 183 | return 0; 184 | 185 | i += count - 1; 186 | } 187 | } 188 | 189 | return 1; 190 | } 191 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([cpuminer], [2.3.2]) 2 | 3 | AC_PREREQ([2.59c]) 4 | AC_CANONICAL_SYSTEM 5 | AC_CONFIG_SRCDIR([cpu-miner.c]) 6 | AM_INIT_AUTOMAKE([gnu]) 7 | AC_CONFIG_HEADERS([cpuminer-config.h]) 8 | 9 | dnl Make sure anyone changing configure.ac/Makefile.am has a clue 10 | AM_MAINTAINER_MODE 11 | 12 | dnl Checks for programs 13 | AC_PROG_CC_C99 14 | AC_PROG_GCC_TRADITIONAL 15 | AM_PROG_CC_C_O 16 | AM_PROG_AS 17 | AC_PROG_RANLIB 18 | 19 | dnl Checks for header files 20 | AC_HEADER_STDC 21 | AC_CHECK_HEADERS([sys/endian.h sys/param.h syslog.h]) 22 | # sys/sysctl.h requires sys/types.h on FreeBSD 23 | # sys/sysctl.h requires sys/param.h on OpenBSD 24 | AC_CHECK_HEADERS([sys/sysctl.h], [], [], 25 | [#include 26 | #ifdef HAVE_SYS_PARAM_H 27 | #include 28 | #endif 29 | ]) 30 | 31 | AC_CHECK_DECLS([be32dec, le32dec, be32enc, le32enc], [], [], 32 | [AC_INCLUDES_DEFAULT 33 | #ifdef HAVE_SYS_ENDIAN_H 34 | #include 35 | #endif 36 | ]) 37 | 38 | AC_FUNC_ALLOCA 39 | AC_CHECK_FUNCS([getopt_long]) 40 | 41 | case $target in 42 | i*86-*-*) 43 | have_x86=true 44 | ;; 45 | x86_64-*-*|amd64-*-*) 46 | have_x86_64=true 47 | ;; 48 | arm*-*-*) 49 | have_arm=true 50 | ;; 51 | esac 52 | 53 | PTHREAD_FLAGS="-pthread" 54 | WS2_LIBS="" 55 | 56 | case $target in 57 | *-*-mingw*) 58 | have_win32=true 59 | PTHREAD_FLAGS="" 60 | WS2_LIBS="-lws2_32" 61 | ;; 62 | esac 63 | 64 | if test x$have_x86 = xtrue -o x$have_x86_64 = xtrue 65 | then 66 | AC_MSG_CHECKING(whether we can compile AVX code) 67 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[asm ("vmovdqa %ymm0, %ymm1");])], 68 | AC_DEFINE(USE_AVX, 1, [Define to 1 if AVX assembly is available.]) 69 | AC_MSG_RESULT(yes) 70 | AC_MSG_CHECKING(whether we can compile XOP code) 71 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[asm ("vprotd \$7, %xmm0, %xmm1");])], 72 | AC_DEFINE(USE_XOP, 1, [Define to 1 if XOP assembly is available.]) 73 | AC_MSG_RESULT(yes) 74 | , 75 | AC_MSG_RESULT(no) 76 | AC_MSG_WARN([The assembler does not support the XOP instruction set.]) 77 | ) 78 | AC_MSG_CHECKING(whether we can compile AVX2 code) 79 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[asm ("vpaddd %ymm0, %ymm1, %ymm2");])], 80 | AC_DEFINE(USE_AVX2, 1, [Define to 1 if AVX2 assembly is available.]) 81 | AC_MSG_RESULT(yes) 82 | , 83 | AC_MSG_RESULT(no) 84 | AC_MSG_WARN([The assembler does not support the AVX2 instruction set.]) 85 | ) 86 | , 87 | AC_MSG_RESULT(no) 88 | AC_MSG_WARN([The assembler does not support the AVX instruction set.]) 89 | ) 90 | fi 91 | 92 | AC_CHECK_LIB(jansson, json_loads, request_jansson=false, request_jansson=true) 93 | AC_CHECK_LIB([pthread], [pthread_create], PTHREAD_LIBS="-lpthread", 94 | AC_CHECK_LIB([pthreadGC2], [pthread_create], PTHREAD_LIBS="-lpthreadGC2", 95 | AC_CHECK_LIB([pthreadGC1], [pthread_create], PTHREAD_LIBS="-lpthreadGC1", 96 | AC_CHECK_LIB([pthreadGC], [pthread_create], PTHREAD_LIBS="-lpthreadGC" 97 | )))) 98 | 99 | curses="auto" 100 | 101 | AC_ARG_WITH([curses], 102 | [AC_HELP_STRING([--without-curses],[Compile support for curses TUI (default enabled)])], 103 | [curses=$withval] 104 | ) 105 | if test "x$curses" = "xno"; then 106 | cursesmsg='User specified --without-curses. TUI support DISABLED' 107 | else 108 | AC_SEARCH_LIBS(addstr, ncurses pdcurses, [ 109 | curses=yes 110 | cursesmsg="FOUND: ${ac_cv_search_addstr}" 111 | AC_DEFINE([HAVE_CURSES], [1], [Defined to 1 if curses TUI support is wanted]) 112 | ], [ 113 | if test "x$curses" = "xyes"; then 114 | AC_MSG_ERROR([Could not find curses library - please install libncurses-dev or pdcurses-dev (or configure --without-curses)]) 115 | else 116 | AC_MSG_WARN([Could not find curses library - if you want a TUI, install libncurses-dev or pdcurses-dev]) 117 | curses=no 118 | cursesmsg='NOT FOUND. TUI support DISABLED' 119 | fi 120 | ]) 121 | fi 122 | 123 | AC_CHECK_HEADER([libudev.h],[ 124 | libudev=yes 125 | UDEV_LIBS=-ludev 126 | AC_DEFINE([HAVE_LIBUDEV], [1], [Defined to 1 if libudev is wanted]) 127 | ], [ 128 | if test "x$libudev" = "xyes"; then 129 | AC_MSG_ERROR([libudev not found]) 130 | fi 131 | libudev=no 132 | ]) 133 | 134 | AC_CHECK_HEADERS([setupapi.h initguid.h],[ 135 | setupapi=yes 136 | SETUPAPI_LIBS=-lsetupapi 137 | AC_DEFINE([HAVE_SETUPAPI], [1], [Defined to 1 if setupapi is wanted]) 138 | ], [ 139 | if test "x$setupapi" = "xyes"; then 140 | AC_MSG_ERROR([setupapi not found]) 141 | fi 142 | setupapi=no 143 | ], [[ 144 | #ifdef HAVE_SETUPAPI_H 145 | #include 146 | #endif 147 | ]]) 148 | 149 | AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue]) 150 | AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes]) 151 | AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue]) 152 | AM_CONDITIONAL([ARCH_x86], [test x$have_x86 = xtrue]) 153 | AM_CONDITIONAL([ARCH_x86_64], [test x$have_x86_64 = xtrue]) 154 | AM_CONDITIONAL([ARCH_ARM], [test x$have_arm = xtrue]) 155 | 156 | if test x$request_jansson = xtrue 157 | then 158 | JANSSON_LIBS="compat/jansson/libjansson.a" 159 | else 160 | JANSSON_LIBS=-ljansson 161 | fi 162 | 163 | LIBCURL_CHECK_CONFIG(, 7.15.2, , 164 | [AC_MSG_ERROR([Missing required libcurl >= 7.15.2])]) 165 | 166 | AC_SUBST(JANSSON_LIBS) 167 | AC_SUBST(PTHREAD_FLAGS) 168 | AC_SUBST(PTHREAD_LIBS) 169 | AC_SUBST(WS2_LIBS) 170 | AC_SUBST(NCURSES_LIBS) 171 | AC_SUBST(PDCURSES_LIBS) 172 | AC_SUBST(UDEV_LIBS) 173 | AC_SUBST(SETUPAPI_LIBS) 174 | 175 | AC_CONFIG_FILES([ 176 | Makefile 177 | compat/Makefile 178 | compat/jansson/Makefile 179 | ]) 180 | AC_OUTPUT 181 | -------------------------------------------------------------------------------- /compat/jansson/jansson.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef JANSSON_H 9 | #define JANSSON_H 10 | 11 | #include 12 | 13 | #ifndef __cplusplus 14 | #define JSON_INLINE inline 15 | #else 16 | #define JSON_INLINE inline 17 | extern "C" { 18 | #endif 19 | 20 | /* types */ 21 | 22 | typedef enum { 23 | JSON_OBJECT, 24 | JSON_ARRAY, 25 | JSON_STRING, 26 | JSON_INTEGER, 27 | JSON_REAL, 28 | JSON_TRUE, 29 | JSON_FALSE, 30 | JSON_NULL 31 | } json_type; 32 | 33 | typedef struct { 34 | json_type type; 35 | unsigned long refcount; 36 | } json_t; 37 | 38 | #define json_typeof(json) ((json)->type) 39 | #define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT) 40 | #define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY) 41 | #define json_is_string(json) (json && json_typeof(json) == JSON_STRING) 42 | #define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER) 43 | #define json_is_real(json) (json && json_typeof(json) == JSON_REAL) 44 | #define json_is_number(json) (json_is_integer(json) || json_is_real(json)) 45 | #define json_is_true(json) (json && json_typeof(json) == JSON_TRUE) 46 | #define json_is_false(json) (json && json_typeof(json) == JSON_FALSE) 47 | #define json_is_boolean(json) (json_is_true(json) || json_is_false(json)) 48 | #define json_is_null(json) (json && json_typeof(json) == JSON_NULL) 49 | 50 | /* construction, destruction, reference counting */ 51 | 52 | json_t *json_object(void); 53 | json_t *json_array(void); 54 | json_t *json_string(const char *value); 55 | json_t *json_string_nocheck(const char *value); 56 | json_t *json_integer(int value); 57 | json_t *json_real(double value); 58 | json_t *json_true(void); 59 | json_t *json_false(void); 60 | json_t *json_null(void); 61 | 62 | static JSON_INLINE 63 | json_t *json_incref(json_t *json) 64 | { 65 | if(json && json->refcount != (unsigned int)-1) 66 | ++json->refcount; 67 | return json; 68 | } 69 | 70 | /* do not call json_delete directly */ 71 | void json_delete(json_t *json); 72 | 73 | static JSON_INLINE 74 | void json_decref(json_t *json) 75 | { 76 | if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0) 77 | json_delete(json); 78 | } 79 | 80 | 81 | /* getters, setters, manipulation */ 82 | 83 | unsigned int json_object_size(const json_t *object); 84 | json_t *json_object_get(const json_t *object, const char *key); 85 | int json_object_set_new(json_t *object, const char *key, json_t *value); 86 | int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value); 87 | int json_object_del(json_t *object, const char *key); 88 | int json_object_clear(json_t *object); 89 | int json_object_update(json_t *object, json_t *other); 90 | void *json_object_iter(json_t *object); 91 | void *json_object_iter_at(json_t *object, const char *key); 92 | void *json_object_iter_next(json_t *object, void *iter); 93 | const char *json_object_iter_key(void *iter); 94 | json_t *json_object_iter_value(void *iter); 95 | int json_object_iter_set_new(json_t *object, void *iter, json_t *value); 96 | 97 | static JSON_INLINE 98 | int json_object_set(json_t *object, const char *key, json_t *value) 99 | { 100 | return json_object_set_new(object, key, json_incref(value)); 101 | } 102 | 103 | static JSON_INLINE 104 | int json_object_set_nocheck(json_t *object, const char *key, json_t *value) 105 | { 106 | return json_object_set_new_nocheck(object, key, json_incref(value)); 107 | } 108 | 109 | static inline 110 | int json_object_iter_set(json_t *object, void *iter, json_t *value) 111 | { 112 | return json_object_iter_set_new(object, iter, json_incref(value)); 113 | } 114 | 115 | unsigned int json_array_size(const json_t *array); 116 | json_t *json_array_get(const json_t *array, unsigned int index); 117 | int json_array_set_new(json_t *array, unsigned int index, json_t *value); 118 | int json_array_append_new(json_t *array, json_t *value); 119 | int json_array_insert_new(json_t *array, unsigned int index, json_t *value); 120 | int json_array_remove(json_t *array, unsigned int index); 121 | int json_array_clear(json_t *array); 122 | int json_array_extend(json_t *array, json_t *other); 123 | 124 | static JSON_INLINE 125 | int json_array_set(json_t *array, unsigned int index, json_t *value) 126 | { 127 | return json_array_set_new(array, index, json_incref(value)); 128 | } 129 | 130 | static JSON_INLINE 131 | int json_array_append(json_t *array, json_t *value) 132 | { 133 | return json_array_append_new(array, json_incref(value)); 134 | } 135 | 136 | static JSON_INLINE 137 | int json_array_insert(json_t *array, unsigned int index, json_t *value) 138 | { 139 | return json_array_insert_new(array, index, json_incref(value)); 140 | } 141 | 142 | const char *json_string_value(const json_t *string); 143 | int json_integer_value(const json_t *integer); 144 | double json_real_value(const json_t *real); 145 | double json_number_value(const json_t *json); 146 | 147 | int json_string_set(json_t *string, const char *value); 148 | int json_string_set_nocheck(json_t *string, const char *value); 149 | int json_integer_set(json_t *integer, int value); 150 | int json_real_set(json_t *real, double value); 151 | 152 | 153 | /* equality */ 154 | 155 | int json_equal(json_t *value1, json_t *value2); 156 | 157 | 158 | /* copying */ 159 | 160 | json_t *json_copy(json_t *value); 161 | json_t *json_deep_copy(json_t *value); 162 | 163 | 164 | /* loading, printing */ 165 | 166 | #define JSON_ERROR_TEXT_LENGTH 160 167 | 168 | typedef struct { 169 | char text[JSON_ERROR_TEXT_LENGTH]; 170 | int line; 171 | } json_error_t; 172 | 173 | json_t *json_loads(const char *input, json_error_t *error); 174 | json_t *json_loadf(FILE *input, json_error_t *error); 175 | json_t *json_load_file(const char *path, json_error_t *error); 176 | 177 | #define JSON_INDENT(n) (n & 0xFF) 178 | #define JSON_COMPACT 0x100 179 | #define JSON_ENSURE_ASCII 0x200 180 | #define JSON_SORT_KEYS 0x400 181 | #define JSON_PRESERVE_ORDER 0x800 182 | 183 | char *json_dumps(const json_t *json, unsigned long flags); 184 | int json_dumpf(const json_t *json, FILE *output, unsigned long flags); 185 | int json_dump_file(const json_t *json, const char *path, unsigned long flags); 186 | 187 | #ifdef __cplusplus 188 | } 189 | #endif 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /compat/jansson/hashtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef HASHTABLE_H 9 | #define HASHTABLE_H 10 | 11 | typedef unsigned int (*key_hash_fn)(const void *key); 12 | typedef int (*key_cmp_fn)(const void *key1, const void *key2); 13 | typedef void (*free_fn)(void *key); 14 | 15 | struct hashtable_list { 16 | struct hashtable_list *prev; 17 | struct hashtable_list *next; 18 | }; 19 | 20 | struct hashtable_pair { 21 | void *key; 22 | void *value; 23 | unsigned int hash; 24 | struct hashtable_list list; 25 | }; 26 | 27 | struct hashtable_bucket { 28 | struct hashtable_list *first; 29 | struct hashtable_list *last; 30 | }; 31 | 32 | typedef struct hashtable { 33 | unsigned int size; 34 | struct hashtable_bucket *buckets; 35 | unsigned int num_buckets; /* index to primes[] */ 36 | struct hashtable_list list; 37 | 38 | key_hash_fn hash_key; 39 | key_cmp_fn cmp_keys; /* returns non-zero for equal keys */ 40 | free_fn free_key; 41 | free_fn free_value; 42 | } hashtable_t; 43 | 44 | /** 45 | * hashtable_create - Create a hashtable object 46 | * 47 | * @hash_key: The key hashing function 48 | * @cmp_keys: The key compare function. Returns non-zero for equal and 49 | * zero for unequal unequal keys 50 | * @free_key: If non-NULL, called for a key that is no longer referenced. 51 | * @free_value: If non-NULL, called for a value that is no longer referenced. 52 | * 53 | * Returns a new hashtable object that should be freed with 54 | * hashtable_destroy when it's no longer used, or NULL on failure (out 55 | * of memory). 56 | */ 57 | hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, 58 | free_fn free_key, free_fn free_value); 59 | 60 | /** 61 | * hashtable_destroy - Destroy a hashtable object 62 | * 63 | * @hashtable: The hashtable 64 | * 65 | * Destroys a hashtable created with hashtable_create(). 66 | */ 67 | void hashtable_destroy(hashtable_t *hashtable); 68 | 69 | /** 70 | * hashtable_init - Initialize a hashtable object 71 | * 72 | * @hashtable: The (statically allocated) hashtable object 73 | * @hash_key: The key hashing function 74 | * @cmp_keys: The key compare function. Returns non-zero for equal and 75 | * zero for unequal unequal keys 76 | * @free_key: If non-NULL, called for a key that is no longer referenced. 77 | * @free_value: If non-NULL, called for a value that is no longer referenced. 78 | * 79 | * Initializes a statically allocated hashtable object. The object 80 | * should be cleared with hashtable_close when it's no longer used. 81 | * 82 | * Returns 0 on success, -1 on error (out of memory). 83 | */ 84 | int hashtable_init(hashtable_t *hashtable, 85 | key_hash_fn hash_key, key_cmp_fn cmp_keys, 86 | free_fn free_key, free_fn free_value); 87 | 88 | /** 89 | * hashtable_close - Release all resources used by a hashtable object 90 | * 91 | * @hashtable: The hashtable 92 | * 93 | * Destroys a statically allocated hashtable object. 94 | */ 95 | void hashtable_close(hashtable_t *hashtable); 96 | 97 | /** 98 | * hashtable_set - Add/modify value in hashtable 99 | * 100 | * @hashtable: The hashtable object 101 | * @key: The key 102 | * @value: The value 103 | * 104 | * If a value with the given key already exists, its value is replaced 105 | * with the new value. 106 | * 107 | * Key and value are "stealed" in the sense that hashtable frees them 108 | * automatically when they are no longer used. The freeing is 109 | * accomplished by calling free_key and free_value functions that were 110 | * supplied to hashtable_new. In case one or both of the free 111 | * functions is NULL, the corresponding item is not "stealed". 112 | * 113 | * Returns 0 on success, -1 on failure (out of memory). 114 | */ 115 | int hashtable_set(hashtable_t *hashtable, void *key, void *value); 116 | 117 | /** 118 | * hashtable_get - Get a value associated with a key 119 | * 120 | * @hashtable: The hashtable object 121 | * @key: The key 122 | * 123 | * Returns value if it is found, or NULL otherwise. 124 | */ 125 | void *hashtable_get(hashtable_t *hashtable, const void *key); 126 | 127 | /** 128 | * hashtable_del - Remove a value from the hashtable 129 | * 130 | * @hashtable: The hashtable object 131 | * @key: The key 132 | * 133 | * Returns 0 on success, or -1 if the key was not found. 134 | */ 135 | int hashtable_del(hashtable_t *hashtable, const void *key); 136 | 137 | /** 138 | * hashtable_clear - Clear hashtable 139 | * 140 | * @hashtable: The hashtable object 141 | * 142 | * Removes all items from the hashtable. 143 | */ 144 | void hashtable_clear(hashtable_t *hashtable); 145 | 146 | /** 147 | * hashtable_iter - Iterate over hashtable 148 | * 149 | * @hashtable: The hashtable object 150 | * 151 | * Returns an opaque iterator to the first element in the hashtable. 152 | * The iterator should be passed to hashtable_iter_* functions. 153 | * The hashtable items are not iterated over in any particular order. 154 | * 155 | * There's no need to free the iterator in any way. The iterator is 156 | * valid as long as the item that is referenced by the iterator is not 157 | * deleted. Other values may be added or deleted. In particular, 158 | * hashtable_iter_next() may be called on an iterator, and after that 159 | * the key/value pair pointed by the old iterator may be deleted. 160 | */ 161 | void *hashtable_iter(hashtable_t *hashtable); 162 | 163 | /** 164 | * hashtable_iter_at - Return an iterator at a specific key 165 | * 166 | * @hashtable: The hashtable object 167 | * @key: The key that the iterator should point to 168 | * 169 | * Like hashtable_iter() but returns an iterator pointing to a 170 | * specific key. 171 | */ 172 | void *hashtable_iter_at(hashtable_t *hashtable, const void *key); 173 | 174 | /** 175 | * hashtable_iter_next - Advance an iterator 176 | * 177 | * @hashtable: The hashtable object 178 | * @iter: The iterator 179 | * 180 | * Returns a new iterator pointing to the next element in the 181 | * hashtable or NULL if the whole hastable has been iterated over. 182 | */ 183 | void *hashtable_iter_next(hashtable_t *hashtable, void *iter); 184 | 185 | /** 186 | * hashtable_iter_key - Retrieve the key pointed by an iterator 187 | * 188 | * @iter: The iterator 189 | */ 190 | void *hashtable_iter_key(void *iter); 191 | 192 | /** 193 | * hashtable_iter_value - Retrieve the value pointed by an iterator 194 | * 195 | * @iter: The iterator 196 | */ 197 | void *hashtable_iter_value(void *iter); 198 | 199 | /** 200 | * hashtable_iter_set - Set the value pointed by an iterator 201 | * 202 | * @iter: The iterator 203 | * @value: The value to set 204 | */ 205 | void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value); 206 | 207 | #endif 208 | -------------------------------------------------------------------------------- /minerd.1: -------------------------------------------------------------------------------- 1 | .TH MINERD 1 "November 2013" "cpuminer 2.3.2" 2 | .SH NAME 3 | minerd \- CPU miner for Bitcoin and Litecoin 4 | .SH SYNOPSIS 5 | .B minerd 6 | [\fIOPTION\fR]... 7 | .SH DESCRIPTION 8 | .B minerd 9 | is a multi-threaded CPU miner for Bitcoin, Litecoin and other cryptocurrencies. 10 | It supports the getwork mining protocol as well as the Stratum mining protocol. 11 | .PP 12 | In its normal mode of operation, \fBminerd\fR connects to a mining server 13 | (specified with the \fB\-o\fR option), receives work from it and starts hashing. 14 | As soon as a solution is found, it is submitted to the same mining server, 15 | which can accept or reject it. 16 | When using the getwork protocol, \fBminerd\fR can take advantage 17 | of the long polling extension, if the server supports it; 18 | in any case, fresh work is fetched as needed. 19 | When using the Stratum protocol this is not possible, 20 | and the server is responsible for sending fresh work at least every minute; 21 | if it fails to do so, 22 | \fBminerd\fR may drop the connection and try reconnecting again. 23 | .PP 24 | By default, \fBminerd\fR writes all its messages to standard error. 25 | On systems that have a syslog, the \fB\-\-syslog\fR option can be used 26 | to write to it instead. 27 | .PP 28 | On start, the nice value of all miner threads is set to 19. 29 | On Linux, the scheduling policy is also changed to SCHED_IDLE, 30 | or to SCHED_BATCH if that fails. 31 | On multiprocessor systems, \fBminerd\fR 32 | automatically sets the CPU affinity of miner threads 33 | if the number of threads is a multiple of the number of processors. 34 | .SH EXAMPLES 35 | To connect to a Litecoin mining pool that provides a Stratum server 36 | at example.com on port 3333, authenticating as worker "foo" with password "bar": 37 | .PP 38 | .nf 39 | .RS 40 | minerd \-o stratum+tcp://example.com:3333 \-O foo:bar 41 | .RE 42 | .fi 43 | .PP 44 | To mine to a local Bitcoin testnet instance running on port 18332, 45 | authenticating with username "rpcuser" and password "rpcpass": 46 | .PP 47 | .nf 48 | .RS 49 | minerd \-a sha256d \-o http://localhost:18332 \-O rpcuser:rpcpass 50 | .RE 51 | .fi 52 | .PP 53 | To connect to a Litecoin P2Pool node running on my.server on port 9327, 54 | mining in the background and having output sent to the syslog facility, 55 | omitting the per-thread hashmeter output: 56 | .PP 57 | .nf 58 | .RS 59 | minerd \-BSq \-o http://my.server:9327 60 | .RE 61 | .fi 62 | .SH OPTIONS 63 | .TP 64 | \fB\-a\fR, \fB\-\-algo\fR=\fIALGORITHM\fR 65 | Set the hashing algorithm to use. 66 | Default is scrypt. 67 | Possible values are: 68 | .RS 11 69 | .TP 10 70 | .B scrypt 71 | scrypt(1024, 1, 1) (used by Litecoin) 72 | .TP 73 | .B sha256d 74 | SHA-256d (used by Bitcoin) 75 | .RE 76 | .TP 77 | \fB\-\-benchmark\fR 78 | Run in offline benchmark mode. 79 | .TP 80 | \fB\-B\fR, \fB\-\-background\fR 81 | Run in the background as a daemon. 82 | .TP 83 | \fB\-\-cert\fR=\fIFILE\fR 84 | Set a SSL certificate to use with the mining server. 85 | Only supported when using the HTTPS protocol. 86 | .TP 87 | \fB\-c\fR, \fB\-\-config\fR=\fIFILE\fR 88 | Load options from a configuration file. 89 | \fIFILE\fR must contain a JSON object 90 | mapping long options to their arguments (as strings), 91 | or to \fBtrue\fR if no argument is required. 92 | Sample configuration file: 93 | 94 | .nf 95 | { 96 | "url": "stratum+tcp://example.com:3333", 97 | "userpass": "foo:bar", 98 | "retry-pause": "10", 99 | "quiet": true 100 | } 101 | .fi 102 | .TP 103 | \fB\-D\fR, \fB\-\-debug\fR 104 | Enable debug output. 105 | .TP 106 | \fB\-h\fR, \fB\-\-help\fR 107 | Print a help message and exit. 108 | .TP 109 | \fB\-\-no\-longpoll\fR 110 | Do not use long polling. 111 | .TP 112 | \fB\-\-no\-stratum\fR 113 | Do not switch to Stratum, even if the server advertises support for it. 114 | .TP 115 | \fB\-o\fR, \fB\-\-url\fR=[\fISCHEME\fR://][\fIUSERNAME\fR[:\fIPASSWORD\fR]@]\fIHOST\fR:\fIPORT\fR[/\fIPATH\fR] 116 | Set the URL of the mining server to connect to. 117 | Supported schemes are \fBhttp\fR, \fBhttps\fR and \fBstratum+tcp\fR. 118 | If no scheme is specified, http is used. 119 | Specifying a \fIPATH\fR is only supported for HTTP and HTTPS. 120 | Specifying credentials has the same effect as using the \fB\-O\fR option. 121 | If no mining server is provided, 122 | the miner will try to connect to http://127.0.0.1:9332/, 123 | corresponding to the default settings for a local Litecoin daemon. 124 | .TP 125 | \fB\-O\fR, \fB\-\-userpass\fR=\fIUSERNAME\fR:\fIPASSWORD\fR 126 | Set the credentials to use for connecting to the mining server. 127 | Any value previously set with \fB\-u\fR or \fB\-p\fR is discarded. 128 | .TP 129 | \fB\-p\fR, \fB\-\-pass\fR=\fIPASSWORD\fR 130 | Set the password to use for connecting to the mining server. 131 | Any password previously set with \fB\-O\fR is discarded. 132 | .TP 133 | \fB\-P\fR, \fB\-\-protocol\-dump\fR 134 | Enable output of all protocol-level activities. 135 | .TP 136 | \fB\-q\fR, \fB\-\-quiet\fR 137 | Disable per-thread hashmeter output. 138 | .TP 139 | \fB\-r\fR, \fB\-\-retries\fR=\fIN\fR 140 | Set the maximum number of times to retry if a network call fails. 141 | If not specified, the miner will retry indefinitely. 142 | .TP 143 | \fB\-R\fR, \fB\-\-retry\-pause\fR=\fISECONDS\fR 144 | Set how long to wait between retries. Default is 30 seconds. 145 | .TP 146 | \fB\-s\fR, \fB\-\-scantime\fR=\fISECONDS\fR 147 | Set an upper bound on the time the miner can go without fetching fresh work. 148 | This setting has no effect in Stratum mode or when long polling is activated. 149 | Default is 5 seconds. 150 | .TP 151 | \fB\-S\fR, \fB\-\-syslog\fR 152 | Log to the syslog facility instead of standard error. 153 | .TP 154 | \fB\-t\fR, \fB\-\-threads\fR=\fIN\fR 155 | Set the number of miner threads. 156 | If not specified, the miner will try to detect the number of available processors 157 | and use that. 158 | .TP 159 | \fB\-T\fR, \fB\-\-timeout\fR=\fISECONDS\fR 160 | Set the timeout for long polling. Default is 270 seconds. 161 | .TP 162 | \fB\-u\fR, \fB\-\-user\fR=\fIUSERNAME\fR 163 | Set the username to use for connecting to the mining server. 164 | Any username previously set with \fB\-O\fR is discarded. 165 | .TP 166 | \fB\-V\fR, \fB\-\-version\fR 167 | Display version information and quit. 168 | .TP 169 | \fB\-x\fR, \fB\-\-proxy\fR=[\fISCHEME\fR://]\fIHOST\fR:\fIPORT\fR 170 | Connect to the mining server through a proxy. 171 | Supported schemes are: \fBhttp\fR, \fBsocks4\fR, \fBsocks5\fR. 172 | Since libcurl 7.18.0, the following are also supported: 173 | \fBsocks4a\fR, \fBsocks5h\fR (SOCKS5 with remote name resolving). 174 | If no scheme is specified, the proxy is treated as an HTTP proxy. 175 | HTTP proxies cannot be used to connect to Stratum servers. 176 | .SH ENVIRONMENT 177 | The following environment variables can be specified in lower case or upper case; 178 | the lower-case version has precedence. \fBhttp_proxy\fR is an exception 179 | as it is only available in lower case. 180 | .PP 181 | .RS 182 | .TP 183 | \fBhttp_proxy\fR [\fISCHEME\fR://]\fIHOST\fR:\fIPORT\fR 184 | Sets the proxy server to use for HTTP. 185 | .TP 186 | \fBHTTPS_PROXY\fR [\fISCHEME\fR://]\fIHOST\fR:\fIPORT\fR 187 | Sets the proxy server to use for HTTPS. 188 | .TP 189 | \fBALL_PROXY\fR [\fISCHEME\fR://]\fIHOST\fR:\fIPORT\fR 190 | Sets the proxy server to use if no protocol-specific proxy is set. 191 | .RE 192 | .PP 193 | Using an environment variable to set the proxy has the same effect as 194 | using the \fB\-x\fR option. 195 | .SH AUTHOR 196 | Most of the code in the current version of minerd was written by 197 | Pooler with contributions from others. 198 | 199 | The original minerd was written by Jeff Garzik . 200 | -------------------------------------------------------------------------------- /elist.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_LIST_H 2 | #define _LINUX_LIST_H 3 | 4 | /* 5 | * Simple doubly linked list implementation. 6 | * 7 | * Some of the internal functions ("__xxx") are useful when 8 | * manipulating whole lists rather than single entries, as 9 | * sometimes we already know the next/prev entries and we can 10 | * generate better code by using them directly rather than 11 | * using the generic single-entry routines. 12 | */ 13 | 14 | struct list_head { 15 | struct list_head *next, *prev; 16 | }; 17 | 18 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 19 | 20 | #define LIST_HEAD(name) \ 21 | struct list_head name = LIST_HEAD_INIT(name) 22 | 23 | #define INIT_LIST_HEAD(ptr) do { \ 24 | (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 25 | } while (0) 26 | 27 | /* 28 | * Insert a new entry between two known consecutive entries. 29 | * 30 | * This is only for internal list manipulation where we know 31 | * the prev/next entries already! 32 | */ 33 | static inline void __list_add(struct list_head *new, 34 | struct list_head *prev, 35 | struct list_head *next) 36 | { 37 | next->prev = new; 38 | new->next = next; 39 | new->prev = prev; 40 | prev->next = new; 41 | } 42 | 43 | /** 44 | * list_add - add a new entry 45 | * @new: new entry to be added 46 | * @head: list head to add it after 47 | * 48 | * Insert a new entry after the specified head. 49 | * This is good for implementing stacks. 50 | */ 51 | static inline void list_add(struct list_head *new, struct list_head *head) 52 | { 53 | __list_add(new, head, head->next); 54 | } 55 | 56 | /** 57 | * list_add_tail - add a new entry 58 | * @new: new entry to be added 59 | * @head: list head to add it before 60 | * 61 | * Insert a new entry before the specified head. 62 | * This is useful for implementing queues. 63 | */ 64 | static inline void list_add_tail(struct list_head *new, struct list_head *head) 65 | { 66 | __list_add(new, head->prev, head); 67 | } 68 | 69 | /* 70 | * Delete a list entry by making the prev/next entries 71 | * point to each other. 72 | * 73 | * This is only for internal list manipulation where we know 74 | * the prev/next entries already! 75 | */ 76 | static inline void __list_del(struct list_head *prev, struct list_head *next) 77 | { 78 | next->prev = prev; 79 | prev->next = next; 80 | } 81 | 82 | /** 83 | * list_del - deletes entry from list. 84 | * @entry: the element to delete from the list. 85 | * Note: list_empty on entry does not return true after this, the entry is in an undefined state. 86 | */ 87 | static inline void list_del(struct list_head *entry) 88 | { 89 | __list_del(entry->prev, entry->next); 90 | entry->next = (void *) 0; 91 | entry->prev = (void *) 0; 92 | } 93 | 94 | /** 95 | * list_del_init - deletes entry from list and reinitialize it. 96 | * @entry: the element to delete from the list. 97 | */ 98 | static inline void list_del_init(struct list_head *entry) 99 | { 100 | __list_del(entry->prev, entry->next); 101 | INIT_LIST_HEAD(entry); 102 | } 103 | 104 | /** 105 | * list_move - delete from one list and add as another's head 106 | * @list: the entry to move 107 | * @head: the head that will precede our entry 108 | */ 109 | static inline void list_move(struct list_head *list, struct list_head *head) 110 | { 111 | __list_del(list->prev, list->next); 112 | list_add(list, head); 113 | } 114 | 115 | /** 116 | * list_move_tail - delete from one list and add as another's tail 117 | * @list: the entry to move 118 | * @head: the head that will follow our entry 119 | */ 120 | static inline void list_move_tail(struct list_head *list, 121 | struct list_head *head) 122 | { 123 | __list_del(list->prev, list->next); 124 | list_add_tail(list, head); 125 | } 126 | 127 | /** 128 | * list_empty - tests whether a list is empty 129 | * @head: the list to test. 130 | */ 131 | static inline int list_empty(struct list_head *head) 132 | { 133 | return head->next == head; 134 | } 135 | 136 | static inline void __list_splice(struct list_head *list, 137 | struct list_head *head) 138 | { 139 | struct list_head *first = list->next; 140 | struct list_head *last = list->prev; 141 | struct list_head *at = head->next; 142 | 143 | first->prev = head; 144 | head->next = first; 145 | 146 | last->next = at; 147 | at->prev = last; 148 | } 149 | 150 | /** 151 | * list_splice - join two lists 152 | * @list: the new list to add. 153 | * @head: the place to add it in the first list. 154 | */ 155 | static inline void list_splice(struct list_head *list, struct list_head *head) 156 | { 157 | if (!list_empty(list)) 158 | __list_splice(list, head); 159 | } 160 | 161 | /** 162 | * list_splice_init - join two lists and reinitialise the emptied list. 163 | * @list: the new list to add. 164 | * @head: the place to add it in the first list. 165 | * 166 | * The list at @list is reinitialised 167 | */ 168 | static inline void list_splice_init(struct list_head *list, 169 | struct list_head *head) 170 | { 171 | if (!list_empty(list)) { 172 | __list_splice(list, head); 173 | INIT_LIST_HEAD(list); 174 | } 175 | } 176 | 177 | /** 178 | * list_entry - get the struct for this entry 179 | * @ptr: the &struct list_head pointer. 180 | * @type: the type of the struct this is embedded in. 181 | * @member: the name of the list_struct within the struct. 182 | */ 183 | #define list_entry(ptr, type, member) \ 184 | ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 185 | 186 | /** 187 | * list_for_each - iterate over a list 188 | * @pos: the &struct list_head to use as a loop counter. 189 | * @head: the head for your list. 190 | */ 191 | #define list_for_each(pos, head) \ 192 | for (pos = (head)->next; pos != (head); \ 193 | pos = pos->next) 194 | /** 195 | * list_for_each_prev - iterate over a list backwards 196 | * @pos: the &struct list_head to use as a loop counter. 197 | * @head: the head for your list. 198 | */ 199 | #define list_for_each_prev(pos, head) \ 200 | for (pos = (head)->prev; pos != (head); \ 201 | pos = pos->prev) 202 | 203 | /** 204 | * list_for_each_safe - iterate over a list safe against removal of list entry 205 | * @pos: the &struct list_head to use as a loop counter. 206 | * @n: another &struct list_head to use as temporary storage 207 | * @head: the head for your list. 208 | */ 209 | #define list_for_each_safe(pos, n, head) \ 210 | for (pos = (head)->next, n = pos->next; pos != (head); \ 211 | pos = n, n = pos->next) 212 | 213 | /** 214 | * list_for_each_entry - iterate over list of given type 215 | * @pos: the type * to use as a loop counter. 216 | * @head: the head for your list. 217 | * @member: the name of the list_struct within the struct. 218 | */ 219 | #define list_for_each_entry(pos, head, member) \ 220 | for (pos = list_entry((head)->next, typeof(*pos), member); \ 221 | &pos->member != (head); \ 222 | pos = list_entry(pos->member.next, typeof(*pos), member)) 223 | 224 | /** 225 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 226 | * @pos: the type * to use as a loop counter. 227 | * @n: another type * to use as temporary storage 228 | * @head: the head for your list. 229 | * @member: the name of the list_struct within the struct. 230 | */ 231 | #define list_for_each_entry_safe(pos, n, head, member) \ 232 | for (pos = list_entry((head)->next, typeof(*pos), member), \ 233 | n = list_entry(pos->member.next, typeof(*pos), member); \ 234 | &pos->member != (head); \ 235 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) 236 | 237 | /** 238 | * list_for_each_entry_continue - iterate over list of given type 239 | * continuing after existing point 240 | * @pos: the type * to use as a loop counter. 241 | * @head: the head for your list. 242 | * @member: the name of the list_struct within the struct. 243 | */ 244 | #define list_for_each_entry_continue(pos, head, member) \ 245 | for (pos = list_entry(pos->member.next, typeof(*pos), member), \ 246 | prefetch(pos->member.next); \ 247 | &pos->member != (head); \ 248 | pos = list_entry(pos->member.next, typeof(*pos), member), \ 249 | prefetch(pos->member.next)) 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Version 2.3.2 - Jul 10, 2013 2 | 3 | - Add optimizations for AVX2-capable x86-64 processors 4 | - Ensure that the output stream is flushed after every log message 5 | - Fix an undefined-behavior bug in the Stratum code 6 | 7 | Version 2.3.1 - Jun 18, 2013 8 | 9 | - Add a --cert option for specifying an SSL certificate (martinwguy) 10 | - Fix a bug that only made SHA-256d mining work at difficulty 1 11 | - Fix a couple of compatibility issues with some Stratum servers 12 | 13 | Version 2.3 - Jun 12, 2013 14 | 15 | - Add support for the Stratum mining protocol 16 | - Automatically switch to Stratum if the mining server supports 17 | the X-Stratum extension, unless --no-stratum is used 18 | - Set CPU affinity on FreeBSD (lye) 19 | - Fix a bug in libcurl initialization (martinwguy) 20 | 21 | Version 2.2.3 - Aug 5, 2012 22 | 23 | - Add optimized ARM NEON code for scrypt and SHA-256d 24 | - Add a --benchmark option that allows offline testing 25 | - Support for the X-Reject-Reason extension 26 | 27 | Version 2.2.2 - Jun 7, 2012 28 | 29 | - Various performance improvements for x86 and x86-64 30 | - Optimize scrypt for ARMv5E and later processors 31 | - Set the priority of miner threads to idle on Windows 32 | - Add an option to start minerd as a daemon on POSIX systems 33 | 34 | Version 2.2.1 - May 2, 2012 35 | 36 | - Add optimized code for ARM processors 37 | - Support for building on NetBSD and OpenBSD 38 | - Various compatibility fixes for AIX (pontius) 39 | 40 | Version 2.2 - Apr 2, 2012 41 | 42 | - Add an optimized SHA-256d algorithm, with specialized code 43 | for x86 and x86-64 and support for AVX and XOP instructions 44 | - Slight performance increase for scrypt on x86 and x86-64 45 | - The default timeout is now 270 seconds 46 | 47 | Version 2.1.5 - Mar 7, 2012 48 | 49 | - Add optimizations for AVX-capable x86-64 processors 50 | - Assume HTTP if no protocol is specified for the mining server 51 | - Fix MinGW compatibility issues and update build instructions 52 | - Add support for building on Solaris using gcc (pontius) 53 | 54 | Version 2.1.4 - Feb 28, 2012 55 | 56 | - Implement 4-way SHA-256 on x86-64 57 | - Add TCP keepalive to long polling connections 58 | - Support HTTP and SOCKS proxies via the --proxy option 59 | - Username and password are no longer mandatory 60 | - Add a script that makes assembly code compatible with old versions 61 | of the GNU assembler that do not support macros 62 | 63 | Version 2.1.3 - Feb 12, 2012 64 | 65 | - Smart handling of long polling failures: switch to short scan time 66 | if long polling fails, and only try to reactivate it if the server 67 | continues to advertise the feature in HTTP headers 68 | - Add "X-Mining-Extensions: midstate" to HTTP headers (p2k) 69 | - Add support for the "submitold" extension, used by p2pool 70 | - It is now possible to specify username and password in the URL, 71 | like this: http://username:password@host:port/ 72 | - Add a --version option, and clean up --help output 73 | - Avoid division by zero when computing hash rates 74 | - Handle empty responses properly (TimothyA) 75 | - Eliminate the delay between starting threads 76 | 77 | Version 2.1.2 - Jan 26, 2012 78 | 79 | - Do not submit work that is known to be stale 80 | - Allow miner threads to ask for new work if the current one is at least 81 | 45 seconds old and long polling is enabled 82 | - Refresh work when long polling times out 83 | - Fix minor speed regression 84 | - Modify x86-64 code to make it compatible with older versions of binutils 85 | 86 | Version 2.1.1 - Jan 20, 2012 87 | 88 | - Handle network errors properly 89 | - Make scantime retargeting more accurate 90 | 91 | Version 2.1 - Jan 19, 2012 92 | 93 | - Share the same work among all threads 94 | - Do not ask for new work if the current one is not expired 95 | - Do not discard the work returned by long polling 96 | 97 | Version 2.0 - Jan 16, 2012 98 | 99 | - Change default port to 9332 for Litecoin and remove default credentials 100 | - Add 'scrypt' as the default algorithm and remove other algorithms (ArtForz) 101 | - Optimize scrypt for x86 and x86-64 102 | - Make scantime retargeting less granular (ArtForz) 103 | - Test the whole hash instead of just looking at the high 32 bits 104 | - Add configurable timeout, with a default of 180 seconds 105 | - Add share summary output (inlikeflynn) 106 | - Fix priority and CPU count detection on Windows 107 | - Fix parameters -u and -p, and add short options -o and -O 108 | 109 | Version 1.0.2 - Jun 13, 2011 110 | 111 | - Linux x86_64 optimisations - Con Kolivas 112 | - Optimise for x86_64 by default by using sse2_64 algo 113 | - Detects CPUs and sets number of threads accordingly 114 | - Uses CPU affinity for each thread where appropriate 115 | - Sets scheduling policy to lowest possible 116 | - Minor performance tweaks 117 | 118 | Version 1.0.1 - May 14, 2011 119 | 120 | - OSX support 121 | 122 | Version 1.0 - May 9, 2011 123 | 124 | - jansson 2.0 compatibility 125 | - correct off-by-one in date (month) display output 126 | - fix platform detection 127 | - improve yasm configure bits 128 | - support full URL, in X-Long-Polling header 129 | 130 | Version 0.8.1 - March 22, 2011 131 | 132 | - Make --user, --pass actually work 133 | 134 | - Add User-Agent HTTP header to requests, so that server operators may 135 | more easily identify the miner client. 136 | 137 | - Fix minor bug in example JSON config file 138 | 139 | Version 0.8 - March 21, 2011 140 | 141 | - Support long polling: http://deepbit.net/longpolling.php 142 | 143 | - Adjust max workload based on scantime (default 5 seconds, 144 | or 60 seconds for longpoll) 145 | 146 | - Standardize program output, and support syslog on Unix platforms 147 | 148 | - Suport --user/--pass options (and "user" and "pass" in config file), 149 | as an alternative to the current --userpass 150 | 151 | Version 0.7.2 - March 14, 2011 152 | 153 | - Add port of ufasoft's sse2 assembly implementation (Linux only) 154 | This is a substantial speed improvement on Intel CPUs. 155 | 156 | - Move all JSON-RPC I/O to separate thread. This reduces the 157 | number of HTTP connections from one-per-thread to one, reducing resource 158 | usage on upstream bitcoind / pool server. 159 | 160 | Version 0.7.1 - March 2, 2011 161 | 162 | - Add support for JSON-format configuration file. See example 163 | file example-cfg.json. Any long argument on the command line 164 | may be stored in the config file. 165 | - Timestamp each solution found 166 | - Improve sha256_4way performance. NOTE: This optimization makes 167 | the 'hash' debug-print output for sha256_way incorrect. 168 | - Use __builtin_expect() intrinsic as compiler micro-optimization 169 | - Build on Intel compiler 170 | - HTTP library now follows HTTP redirects 171 | 172 | Version 0.7 - February 12, 2011 173 | 174 | - Re-use CURL object, thereby reuseing DNS cache and HTTP connections 175 | - Use bswap_32, if compiler intrinsic is not available 176 | - Disable full target validation (as opposed to simply H==0) for now 177 | 178 | Version 0.6.1 - February 4, 2011 179 | 180 | - Fully validate "hash < target", rather than simply stopping our scan 181 | if the high 32 bits are 00000000. 182 | - Add --retry-pause, to set length of pause time between failure retries 183 | - Display proof-of-work hash and target, if -D (debug mode) enabled 184 | - Fix max-nonce auto-adjustment to actually work. This means if your 185 | scan takes longer than 5 seconds (--scantime), the miner will slowly 186 | reduce the number of hashes you work on, before fetching a new work unit. 187 | 188 | Version 0.6 - January 29, 2011 189 | 190 | - Fetch new work unit, if scanhash takes longer than 5 seconds (--scantime) 191 | - BeeCee1's sha256 4way optimizations 192 | - lfm's byte swap optimization (improves via, cryptopp) 193 | - Fix non-working short options -q, -r 194 | 195 | Version 0.5 - December 28, 2010 196 | 197 | - Exit program, when all threads have exited 198 | - Improve JSON-RPC failure diagnostics and resilience 199 | - Add --quiet option, to disable hashmeter output. 200 | 201 | Version 0.3.3 - December 27, 2010 202 | 203 | - Critical fix for sha256_cryptopp 'cryptopp_asm' algo 204 | 205 | Version 0.3.2 - December 23, 2010 206 | 207 | - Critical fix for sha256_via 208 | 209 | Version 0.3.1 - December 19, 2010 210 | 211 | - Critical fix for sha256_via 212 | - Retry JSON-RPC failures (see --retry, under "minerd --help" output) 213 | 214 | Version 0.3 - December 18, 2010 215 | 216 | - Add crypto++ 32bit assembly implementation 217 | - show version upon 'minerd --help' 218 | - work around gcc 4.5.x bug that killed 4way performance 219 | 220 | Version 0.2.2 - December 6, 2010 221 | 222 | - VIA padlock implementation works now 223 | - Minor build and runtime fixes 224 | 225 | Version 0.2.1 - November 29, 2010 226 | 227 | - avoid buffer overflow when submitting solutions 228 | - add Crypto++ sha256 implementation (C only, ASM elided for now) 229 | - minor internal optimizations and cleanups 230 | 231 | Version 0.2 - November 27, 2010 232 | 233 | - Add script for building a Windows installer 234 | - improve hash performance (hashmeter) statistics 235 | - add tcatm 4way sha256 implementation 236 | - Add experimental VIA Padlock sha256 implementation 237 | 238 | Version 0.1.2 - November 26, 2010 239 | 240 | - many small cleanups and micro-optimizations 241 | - build win32 exe using mingw 242 | - RPC URL, username/password become command line arguments 243 | - remove unused OpenSSL dependency 244 | 245 | Version 0.1.1 - November 24, 2010 246 | 247 | - Do not build sha256_generic module separately from cpuminer. 248 | 249 | Version 0.1 - November 24, 2010 250 | 251 | - Initial release. 252 | 253 | -------------------------------------------------------------------------------- /miner.h: -------------------------------------------------------------------------------- 1 | #ifndef __MINER_H__ 2 | #define __MINER_H__ 3 | 4 | #include "cpuminer-config.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef STDC_HEADERS 15 | # include 16 | # include 17 | #else 18 | # ifdef HAVE_STDLIB_H 19 | # include 20 | # endif 21 | #endif 22 | #ifdef HAVE_ALLOCA_H 23 | # include 24 | #elif !defined alloca 25 | # ifdef __GNUC__ 26 | # define alloca __builtin_alloca 27 | # elif defined _AIX 28 | # define alloca __alloca 29 | # elif defined _MSC_VER 30 | # include 31 | # define alloca _alloca 32 | # elif !defined HAVE_ALLOCA 33 | # ifdef __cplusplus 34 | extern "C" 35 | # endif 36 | void *alloca (size_t); 37 | # endif 38 | #endif 39 | 40 | #ifdef HAVE_SYSLOG_H 41 | #include 42 | #else 43 | enum { 44 | LOG_ERR, 45 | LOG_WARNING, 46 | LOG_NOTICE, 47 | LOG_INFO, 48 | LOG_DEBUG, 49 | }; 50 | #endif 51 | 52 | #undef unlikely 53 | #undef likely 54 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) 55 | #define unlikely(expr) (__builtin_expect(!!(expr), 0)) 56 | #define likely(expr) (__builtin_expect(!!(expr), 1)) 57 | #else 58 | #define unlikely(expr) (expr) 59 | #define likely(expr) (expr) 60 | #endif 61 | 62 | #ifndef ARRAY_SIZE 63 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 64 | #endif 65 | 66 | #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) 67 | #define WANT_BUILTIN_BSWAP 68 | #else 69 | #define bswap_32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) \ 70 | | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) 71 | #endif 72 | 73 | static inline uint32_t swab32(uint32_t v) 74 | { 75 | #ifdef WANT_BUILTIN_BSWAP 76 | return __builtin_bswap32(v); 77 | #else 78 | return bswap_32(v); 79 | #endif 80 | } 81 | 82 | #ifdef HAVE_SYS_ENDIAN_H 83 | #include 84 | #endif 85 | 86 | #if !HAVE_DECL_BE32DEC 87 | static inline uint32_t be32dec(const void *pp) 88 | { 89 | const uint8_t *p = (uint8_t const *)pp; 90 | return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + 91 | ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); 92 | } 93 | #endif 94 | 95 | #if !HAVE_DECL_LE32DEC 96 | static inline uint32_t le32dec(const void *pp) 97 | { 98 | const uint8_t *p = (uint8_t const *)pp; 99 | return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + 100 | ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); 101 | } 102 | #endif 103 | 104 | #if !HAVE_DECL_BE32ENC 105 | static inline void be32enc(void *pp, uint32_t x) 106 | { 107 | uint8_t *p = (uint8_t *)pp; 108 | p[3] = x & 0xff; 109 | p[2] = (x >> 8) & 0xff; 110 | p[1] = (x >> 16) & 0xff; 111 | p[0] = (x >> 24) & 0xff; 112 | } 113 | #endif 114 | 115 | #if !HAVE_DECL_LE32ENC 116 | static inline void le32enc(void *pp, uint32_t x) 117 | { 118 | uint8_t *p = (uint8_t *)pp; 119 | p[0] = x & 0xff; 120 | p[1] = (x >> 8) & 0xff; 121 | p[2] = (x >> 16) & 0xff; 122 | p[3] = (x >> 24) & 0xff; 123 | } 124 | #endif 125 | 126 | #if JANSSON_MAJOR_VERSION >= 2 127 | #define JSON_LOADS(str, err_ptr) json_loads((str), 0, (err_ptr)) 128 | #else 129 | #define JSON_LOADS(str, err_ptr) json_loads((str), (err_ptr)) 130 | #endif 131 | 132 | #define USER_AGENT PACKAGE_NAME "/" PACKAGE_VERSION 133 | 134 | void sha256_init(uint32_t *state); 135 | void sha256_transform(uint32_t *state, const uint32_t *block, int swap); 136 | void sha256d(unsigned char *hash, const unsigned char *data, int len); 137 | 138 | #if defined(__ARM_NEON__) || defined(__i386__) || defined(__x86_64__) 139 | #define HAVE_SHA256_4WAY 1 140 | int sha256_use_4way(); 141 | void sha256_init_4way(uint32_t *state); 142 | void sha256_transform_4way(uint32_t *state, const uint32_t *block, int swap); 143 | #endif 144 | 145 | #if defined(__x86_64__) && defined(USE_AVX2) 146 | #define HAVE_SHA256_8WAY 1 147 | int sha256_use_8way(); 148 | void sha256_init_8way(uint32_t *state); 149 | void sha256_transform_8way(uint32_t *state, const uint32_t *block, int swap); 150 | #endif 151 | 152 | extern int scanhash_sha256d(int thr_id, uint32_t *pdata, 153 | const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done); 154 | 155 | extern unsigned char *scrypt_buffer_alloc(); 156 | extern int scanhash_scrypt(int thr_id, uint32_t *pdata, 157 | unsigned char *scratchbuf, const uint32_t *ptarget, 158 | uint32_t max_nonce, unsigned long *hashes_done); 159 | 160 | struct thr_info { 161 | int id; 162 | pthread_t pth; 163 | struct thread_q *q; 164 | }; 165 | 166 | struct work_restart { 167 | volatile unsigned long restart; 168 | char padding[128 - sizeof(unsigned long)]; 169 | }; 170 | 171 | struct display_window 172 | { 173 | WINDOW *win; 174 | unsigned int rows; 175 | unsigned int cols; 176 | unsigned short height; 177 | unsigned short width; 178 | unsigned int py; 179 | unsigned int px; 180 | unsigned short y; 181 | unsigned short x; 182 | }; 183 | struct display 184 | { 185 | struct display_window *top; 186 | struct display_window *summary; 187 | struct display_window *stats; 188 | struct display_window *log; 189 | }; 190 | extern struct display *display; 191 | extern struct display_window* new_win(unsigned short height, unsigned short width, unsigned short y, unsigned short x); 192 | extern struct display_window* new_pad(unsigned int rows, unsigned int cols, unsigned short height, unsigned short width, unsigned short y, unsigned short x); 193 | extern void del_win(struct display_window *win); 194 | extern bool opt_curses; 195 | extern bool opt_log; 196 | extern char *log_path; 197 | #define TUI_SCROLL 2 198 | #define TUI_MIN_LOG 5 199 | #define TUI_MAX_STATS 20 200 | 201 | #ifdef WIN32 202 | #ifndef ASPRINTF_H 203 | #define ASPRINTF_H 204 | #if !defined(vasprintf) 205 | static int vasprintf(char **s, const char *format, va_list ap) 206 | { 207 | /* Guess we need no more than 100 bytes. */ 208 | int n, size = 100; 209 | va_list save_ap; 210 | 211 | if ((*s = (char*) malloc(size)) == NULL) 212 | return -1; 213 | while (1) { 214 | /* wwork on a copy of the va_list because of a bug 215 | in the vsnprintf implementation in x86_64 libc 216 | */ 217 | #ifdef __va_copy 218 | __va_copy(save_ap, ap); 219 | #else 220 | save_ap = ap; 221 | #endif 222 | /* Try to print in the allocated space. */ 223 | n = _vsnprintf(*s, size, format, save_ap); 224 | va_end(save_ap); 225 | /* If that worked, return the string. */ 226 | if (n > -1 && n < size) { 227 | return n; 228 | } 229 | /* Else try again with more space. */ 230 | if (n > -1) { /* glibc 2.1 */ 231 | size = n + 1; /* precisely what is needed */ 232 | } else { /* glibc 2.0 */ 233 | size *= 2; /* twice the old size */ 234 | } 235 | if ((*s = (char*) realloc(*s, size)) == NULL) { 236 | return -1; 237 | } 238 | } 239 | } 240 | #endif 241 | #if !defined(asprintf) 242 | static int asprintf(char **s, const char *format, ...) 243 | { 244 | va_list vals; 245 | int result; 246 | 247 | va_start(vals, format); 248 | result = vasprintf(s, format, vals); 249 | va_end(vals); 250 | return result; 251 | } 252 | #endif 253 | #endif 254 | #endif 255 | 256 | extern bool opt_debug; 257 | extern bool opt_protocol; 258 | extern int opt_timeout; 259 | extern bool want_longpoll; 260 | extern bool have_longpoll; 261 | extern bool want_stratum; 262 | extern bool have_stratum; 263 | extern char *opt_cert; 264 | extern char *opt_proxy; 265 | extern long opt_proxy_type; 266 | extern bool use_syslog; 267 | extern pthread_mutex_t applog_lock; 268 | extern pthread_mutex_t tui_lock; 269 | extern struct thr_info *thr_info; 270 | extern int longpoll_thr_id; 271 | extern int stratum_thr_id; 272 | extern struct work_restart *work_restart; 273 | 274 | extern void applog(int prio, const char *fmt, ...); 275 | extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, 276 | const char *rpc_req, bool, bool, int *); 277 | extern char *bin2hex(const unsigned char *p, size_t len); 278 | extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); 279 | extern int timeval_subtract(struct timeval *result, struct timeval *x, 280 | struct timeval *y); 281 | extern bool fulltest(const uint32_t *hash, const uint32_t *target); 282 | extern void diff_to_target(uint32_t *target, double diff); 283 | 284 | struct stratum_job { 285 | char *job_id; 286 | unsigned char prevhash[32]; 287 | size_t coinbase_size; 288 | unsigned char *coinbase; 289 | unsigned char *xnonce2; 290 | int merkle_count; 291 | unsigned char **merkle; 292 | unsigned char version[4]; 293 | unsigned char nbits[4]; 294 | unsigned char ntime[4]; 295 | bool clean; 296 | double diff; 297 | }; 298 | 299 | struct stratum_ctx { 300 | char *url; 301 | 302 | CURL *curl; 303 | char *curl_url; 304 | char curl_err_str[CURL_ERROR_SIZE]; 305 | curl_socket_t sock; 306 | size_t sockbuf_size; 307 | char *sockbuf; 308 | pthread_mutex_t sock_lock; 309 | 310 | double next_diff; 311 | 312 | char *session_id; 313 | size_t xnonce1_size; 314 | unsigned char *xnonce1; 315 | size_t xnonce2_size; 316 | struct stratum_job job; 317 | pthread_mutex_t work_lock; 318 | }; 319 | 320 | bool stratum_socket_full(struct stratum_ctx *sctx, int timeout); 321 | bool stratum_send_line(struct stratum_ctx *sctx, char *s); 322 | char *stratum_recv_line(struct stratum_ctx *sctx); 323 | bool stratum_connect(struct stratum_ctx *sctx, const char *url); 324 | void stratum_disconnect(struct stratum_ctx *sctx); 325 | bool stratum_subscribe(struct stratum_ctx *sctx); 326 | bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *pass); 327 | bool stratum_handle_method(struct stratum_ctx *sctx, const char *s); 328 | 329 | struct thread_q; 330 | 331 | extern struct thread_q *tq_new(void); 332 | extern void tq_free(struct thread_q *tq); 333 | extern bool tq_push(struct thread_q *tq, void *data); 334 | extern void *tq_pop(struct thread_q *tq, const struct timespec *abstime); 335 | extern void tq_freeze(struct thread_q *tq); 336 | extern void tq_thaw(struct thread_q *tq); 337 | 338 | #endif /* __MINER_H__ */ 339 | -------------------------------------------------------------------------------- /compat/jansson/hashtable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include "hashtable.h" 12 | 13 | typedef struct hashtable_list list_t; 14 | typedef struct hashtable_pair pair_t; 15 | typedef struct hashtable_bucket bucket_t; 16 | 17 | #define container_of(ptr_, type_, member_) \ 18 | ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) 19 | 20 | #define list_to_pair(list_) container_of(list_, pair_t, list) 21 | 22 | static inline void list_init(list_t *list) 23 | { 24 | list->next = list; 25 | list->prev = list; 26 | } 27 | 28 | static inline void list_insert(list_t *list, list_t *node) 29 | { 30 | node->next = list; 31 | node->prev = list->prev; 32 | list->prev->next = node; 33 | list->prev = node; 34 | } 35 | 36 | static inline void list_remove(list_t *list) 37 | { 38 | list->prev->next = list->next; 39 | list->next->prev = list->prev; 40 | } 41 | 42 | static inline int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket) 43 | { 44 | return bucket->first == &hashtable->list && bucket->first == bucket->last; 45 | } 46 | 47 | static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket, 48 | list_t *list) 49 | { 50 | if(bucket_is_empty(hashtable, bucket)) 51 | { 52 | list_insert(&hashtable->list, list); 53 | bucket->first = bucket->last = list; 54 | } 55 | else 56 | { 57 | list_insert(bucket->first, list); 58 | bucket->first = list; 59 | } 60 | } 61 | 62 | static unsigned int primes[] = { 63 | 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 64 | 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 65 | 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 66 | 805306457, 1610612741 67 | }; 68 | static const unsigned int num_primes = sizeof(primes) / sizeof(unsigned int); 69 | 70 | static inline unsigned int num_buckets(hashtable_t *hashtable) 71 | { 72 | return primes[hashtable->num_buckets]; 73 | } 74 | 75 | 76 | static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket, 77 | const void *key, unsigned int hash) 78 | { 79 | list_t *list; 80 | pair_t *pair; 81 | 82 | if(bucket_is_empty(hashtable, bucket)) 83 | return NULL; 84 | 85 | list = bucket->first; 86 | while(1) 87 | { 88 | pair = list_to_pair(list); 89 | if(pair->hash == hash && hashtable->cmp_keys(pair->key, key)) 90 | return pair; 91 | 92 | if(list == bucket->last) 93 | break; 94 | 95 | list = list->next; 96 | } 97 | 98 | return NULL; 99 | } 100 | 101 | /* returns 0 on success, -1 if key was not found */ 102 | static int hashtable_do_del(hashtable_t *hashtable, 103 | const void *key, unsigned int hash) 104 | { 105 | pair_t *pair; 106 | bucket_t *bucket; 107 | unsigned int index; 108 | 109 | index = hash % num_buckets(hashtable); 110 | bucket = &hashtable->buckets[index]; 111 | 112 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 113 | if(!pair) 114 | return -1; 115 | 116 | if(&pair->list == bucket->first && &pair->list == bucket->last) 117 | bucket->first = bucket->last = &hashtable->list; 118 | 119 | else if(&pair->list == bucket->first) 120 | bucket->first = pair->list.next; 121 | 122 | else if(&pair->list == bucket->last) 123 | bucket->last = pair->list.prev; 124 | 125 | list_remove(&pair->list); 126 | 127 | if(hashtable->free_key) 128 | hashtable->free_key(pair->key); 129 | if(hashtable->free_value) 130 | hashtable->free_value(pair->value); 131 | 132 | free(pair); 133 | hashtable->size--; 134 | 135 | return 0; 136 | } 137 | 138 | static void hashtable_do_clear(hashtable_t *hashtable) 139 | { 140 | list_t *list, *next; 141 | pair_t *pair; 142 | 143 | for(list = hashtable->list.next; list != &hashtable->list; list = next) 144 | { 145 | next = list->next; 146 | pair = list_to_pair(list); 147 | if(hashtable->free_key) 148 | hashtable->free_key(pair->key); 149 | if(hashtable->free_value) 150 | hashtable->free_value(pair->value); 151 | free(pair); 152 | } 153 | } 154 | 155 | static int hashtable_do_rehash(hashtable_t *hashtable) 156 | { 157 | list_t *list, *next; 158 | pair_t *pair; 159 | unsigned int i, index, new_size; 160 | 161 | free(hashtable->buckets); 162 | 163 | hashtable->num_buckets++; 164 | new_size = num_buckets(hashtable); 165 | 166 | hashtable->buckets = malloc(new_size * sizeof(bucket_t)); 167 | if(!hashtable->buckets) 168 | return -1; 169 | 170 | for(i = 0; i < num_buckets(hashtable); i++) 171 | { 172 | hashtable->buckets[i].first = hashtable->buckets[i].last = 173 | &hashtable->list; 174 | } 175 | 176 | list = hashtable->list.next; 177 | list_init(&hashtable->list); 178 | 179 | for(; list != &hashtable->list; list = next) { 180 | next = list->next; 181 | pair = list_to_pair(list); 182 | index = pair->hash % new_size; 183 | insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list); 184 | } 185 | 186 | return 0; 187 | } 188 | 189 | 190 | hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys, 191 | free_fn free_key, free_fn free_value) 192 | { 193 | hashtable_t *hashtable = malloc(sizeof(hashtable_t)); 194 | if(!hashtable) 195 | return NULL; 196 | 197 | if(hashtable_init(hashtable, hash_key, cmp_keys, free_key, free_value)) 198 | { 199 | free(hashtable); 200 | return NULL; 201 | } 202 | 203 | return hashtable; 204 | } 205 | 206 | void hashtable_destroy(hashtable_t *hashtable) 207 | { 208 | hashtable_close(hashtable); 209 | free(hashtable); 210 | } 211 | 212 | int hashtable_init(hashtable_t *hashtable, 213 | key_hash_fn hash_key, key_cmp_fn cmp_keys, 214 | free_fn free_key, free_fn free_value) 215 | { 216 | unsigned int i; 217 | 218 | hashtable->size = 0; 219 | hashtable->num_buckets = 0; /* index to primes[] */ 220 | hashtable->buckets = malloc(num_buckets(hashtable) * sizeof(bucket_t)); 221 | if(!hashtable->buckets) 222 | return -1; 223 | 224 | list_init(&hashtable->list); 225 | 226 | hashtable->hash_key = hash_key; 227 | hashtable->cmp_keys = cmp_keys; 228 | hashtable->free_key = free_key; 229 | hashtable->free_value = free_value; 230 | 231 | for(i = 0; i < num_buckets(hashtable); i++) 232 | { 233 | hashtable->buckets[i].first = hashtable->buckets[i].last = 234 | &hashtable->list; 235 | } 236 | 237 | return 0; 238 | } 239 | 240 | void hashtable_close(hashtable_t *hashtable) 241 | { 242 | hashtable_do_clear(hashtable); 243 | free(hashtable->buckets); 244 | } 245 | 246 | int hashtable_set(hashtable_t *hashtable, void *key, void *value) 247 | { 248 | pair_t *pair; 249 | bucket_t *bucket; 250 | unsigned int hash, index; 251 | 252 | /* rehash if the load ratio exceeds 1 */ 253 | if(hashtable->size >= num_buckets(hashtable)) 254 | if(hashtable_do_rehash(hashtable)) 255 | return -1; 256 | 257 | hash = hashtable->hash_key(key); 258 | index = hash % num_buckets(hashtable); 259 | bucket = &hashtable->buckets[index]; 260 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 261 | 262 | if(pair) 263 | { 264 | if(hashtable->free_key) 265 | hashtable->free_key(key); 266 | if(hashtable->free_value) 267 | hashtable->free_value(pair->value); 268 | pair->value = value; 269 | } 270 | else 271 | { 272 | pair = malloc(sizeof(pair_t)); 273 | if(!pair) 274 | return -1; 275 | 276 | pair->key = key; 277 | pair->value = value; 278 | pair->hash = hash; 279 | list_init(&pair->list); 280 | 281 | insert_to_bucket(hashtable, bucket, &pair->list); 282 | 283 | hashtable->size++; 284 | } 285 | return 0; 286 | } 287 | 288 | void *hashtable_get(hashtable_t *hashtable, const void *key) 289 | { 290 | pair_t *pair; 291 | unsigned int hash; 292 | bucket_t *bucket; 293 | 294 | hash = hashtable->hash_key(key); 295 | bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; 296 | 297 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 298 | if(!pair) 299 | return NULL; 300 | 301 | return pair->value; 302 | } 303 | 304 | int hashtable_del(hashtable_t *hashtable, const void *key) 305 | { 306 | unsigned int hash = hashtable->hash_key(key); 307 | return hashtable_do_del(hashtable, key, hash); 308 | } 309 | 310 | void hashtable_clear(hashtable_t *hashtable) 311 | { 312 | unsigned int i; 313 | 314 | hashtable_do_clear(hashtable); 315 | 316 | for(i = 0; i < num_buckets(hashtable); i++) 317 | { 318 | hashtable->buckets[i].first = hashtable->buckets[i].last = 319 | &hashtable->list; 320 | } 321 | 322 | list_init(&hashtable->list); 323 | hashtable->size = 0; 324 | } 325 | 326 | void *hashtable_iter(hashtable_t *hashtable) 327 | { 328 | return hashtable_iter_next(hashtable, &hashtable->list); 329 | } 330 | 331 | void *hashtable_iter_at(hashtable_t *hashtable, const void *key) 332 | { 333 | pair_t *pair; 334 | unsigned int hash; 335 | bucket_t *bucket; 336 | 337 | hash = hashtable->hash_key(key); 338 | bucket = &hashtable->buckets[hash % num_buckets(hashtable)]; 339 | 340 | pair = hashtable_find_pair(hashtable, bucket, key, hash); 341 | if(!pair) 342 | return NULL; 343 | 344 | return &pair->list; 345 | } 346 | 347 | void *hashtable_iter_next(hashtable_t *hashtable, void *iter) 348 | { 349 | list_t *list = (list_t *)iter; 350 | if(list->next == &hashtable->list) 351 | return NULL; 352 | return list->next; 353 | } 354 | 355 | void *hashtable_iter_key(void *iter) 356 | { 357 | pair_t *pair = list_to_pair((list_t *)iter); 358 | return pair->key; 359 | } 360 | 361 | void *hashtable_iter_value(void *iter) 362 | { 363 | pair_t *pair = list_to_pair((list_t *)iter); 364 | return pair->value; 365 | } 366 | 367 | void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value) 368 | { 369 | pair_t *pair = list_to_pair((list_t *)iter); 370 | 371 | if(hashtable->free_value) 372 | hashtable->free_value(pair->value); 373 | 374 | pair->value = value; 375 | } 376 | -------------------------------------------------------------------------------- /compat/jansson/dump.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include "jansson_private.h" 16 | #include "strbuffer.h" 17 | #include "utf.h" 18 | 19 | #define MAX_INTEGER_STR_LENGTH 100 20 | #define MAX_REAL_STR_LENGTH 100 21 | 22 | typedef int (*dump_func)(const char *buffer, int size, void *data); 23 | 24 | struct string 25 | { 26 | char *buffer; 27 | int length; 28 | int size; 29 | }; 30 | 31 | static int dump_to_strbuffer(const char *buffer, int size, void *data) 32 | { 33 | return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); 34 | } 35 | 36 | static int dump_to_file(const char *buffer, int size, void *data) 37 | { 38 | FILE *dest = (FILE *)data; 39 | if(fwrite(buffer, size, 1, dest) != 1) 40 | return -1; 41 | return 0; 42 | } 43 | 44 | /* 256 spaces (the maximum indentation size) */ 45 | static char whitespace[] = " "; 46 | 47 | static int dump_indent(unsigned long flags, int depth, int space, dump_func dump, void *data) 48 | { 49 | if(JSON_INDENT(flags) > 0) 50 | { 51 | int i, ws_count = JSON_INDENT(flags); 52 | 53 | if(dump("\n", 1, data)) 54 | return -1; 55 | 56 | for(i = 0; i < depth; i++) 57 | { 58 | if(dump(whitespace, ws_count, data)) 59 | return -1; 60 | } 61 | } 62 | else if(space && !(flags & JSON_COMPACT)) 63 | { 64 | return dump(" ", 1, data); 65 | } 66 | return 0; 67 | } 68 | 69 | static int dump_string(const char *str, int ascii, dump_func dump, void *data) 70 | { 71 | const char *pos, *end; 72 | int32_t codepoint; 73 | 74 | if(dump("\"", 1, data)) 75 | return -1; 76 | 77 | end = pos = str; 78 | while(1) 79 | { 80 | const char *text; 81 | char seq[13]; 82 | int length; 83 | 84 | while(*end) 85 | { 86 | end = utf8_iterate(pos, &codepoint); 87 | if(!end) 88 | return -1; 89 | 90 | /* mandatory escape or control char */ 91 | if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20) 92 | break; 93 | 94 | /* non-ASCII */ 95 | if(ascii && codepoint > 0x7F) 96 | break; 97 | 98 | pos = end; 99 | } 100 | 101 | if(pos != str) { 102 | if(dump(str, pos - str, data)) 103 | return -1; 104 | } 105 | 106 | if(end == pos) 107 | break; 108 | 109 | /* handle \, ", and control codes */ 110 | length = 2; 111 | switch(codepoint) 112 | { 113 | case '\\': text = "\\\\"; break; 114 | case '\"': text = "\\\""; break; 115 | case '\b': text = "\\b"; break; 116 | case '\f': text = "\\f"; break; 117 | case '\n': text = "\\n"; break; 118 | case '\r': text = "\\r"; break; 119 | case '\t': text = "\\t"; break; 120 | default: 121 | { 122 | /* codepoint is in BMP */ 123 | if(codepoint < 0x10000) 124 | { 125 | sprintf(seq, "\\u%04x", codepoint); 126 | length = 6; 127 | } 128 | 129 | /* not in BMP -> construct a UTF-16 surrogate pair */ 130 | else 131 | { 132 | int32_t first, last; 133 | 134 | codepoint -= 0x10000; 135 | first = 0xD800 | ((codepoint & 0xffc00) >> 10); 136 | last = 0xDC00 | (codepoint & 0x003ff); 137 | 138 | sprintf(seq, "\\u%04x\\u%04x", first, last); 139 | length = 12; 140 | } 141 | 142 | text = seq; 143 | break; 144 | } 145 | } 146 | 147 | if(dump(text, length, data)) 148 | return -1; 149 | 150 | str = pos = end; 151 | } 152 | 153 | return dump("\"", 1, data); 154 | } 155 | 156 | static int object_key_compare_keys(const void *key1, const void *key2) 157 | { 158 | return strcmp((*(const object_key_t **)key1)->key, 159 | (*(const object_key_t **)key2)->key); 160 | } 161 | 162 | static int object_key_compare_serials(const void *key1, const void *key2) 163 | { 164 | return (*(const object_key_t **)key1)->serial - 165 | (*(const object_key_t **)key2)->serial; 166 | } 167 | 168 | static int do_dump(const json_t *json, unsigned long flags, int depth, 169 | dump_func dump, void *data) 170 | { 171 | int ascii = flags & JSON_ENSURE_ASCII ? 1 : 0; 172 | 173 | switch(json_typeof(json)) { 174 | case JSON_NULL: 175 | return dump("null", 4, data); 176 | 177 | case JSON_TRUE: 178 | return dump("true", 4, data); 179 | 180 | case JSON_FALSE: 181 | return dump("false", 5, data); 182 | 183 | case JSON_INTEGER: 184 | { 185 | char buffer[MAX_INTEGER_STR_LENGTH]; 186 | int size; 187 | 188 | size = snprintf(buffer, MAX_INTEGER_STR_LENGTH, "%d", json_integer_value(json)); 189 | if(size >= MAX_INTEGER_STR_LENGTH) 190 | return -1; 191 | 192 | return dump(buffer, size, data); 193 | } 194 | 195 | case JSON_REAL: 196 | { 197 | char buffer[MAX_REAL_STR_LENGTH]; 198 | int size; 199 | 200 | size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%.17g", 201 | json_real_value(json)); 202 | if(size >= MAX_REAL_STR_LENGTH) 203 | return -1; 204 | 205 | /* Make sure there's a dot or 'e' in the output. Otherwise 206 | a real is converted to an integer when decoding */ 207 | if(strchr(buffer, '.') == NULL && 208 | strchr(buffer, 'e') == NULL) 209 | { 210 | if(size + 2 >= MAX_REAL_STR_LENGTH) { 211 | /* No space to append ".0" */ 212 | return -1; 213 | } 214 | buffer[size] = '.'; 215 | buffer[size + 1] = '0'; 216 | size += 2; 217 | } 218 | 219 | return dump(buffer, size, data); 220 | } 221 | 222 | case JSON_STRING: 223 | return dump_string(json_string_value(json), ascii, dump, data); 224 | 225 | case JSON_ARRAY: 226 | { 227 | int i; 228 | int n; 229 | json_array_t *array; 230 | 231 | /* detect circular references */ 232 | array = json_to_array(json); 233 | if(array->visited) 234 | goto array_error; 235 | array->visited = 1; 236 | 237 | n = json_array_size(json); 238 | 239 | if(dump("[", 1, data)) 240 | goto array_error; 241 | if(n == 0) { 242 | array->visited = 0; 243 | return dump("]", 1, data); 244 | } 245 | if(dump_indent(flags, depth + 1, 0, dump, data)) 246 | goto array_error; 247 | 248 | for(i = 0; i < n; ++i) { 249 | if(do_dump(json_array_get(json, i), flags, depth + 1, 250 | dump, data)) 251 | goto array_error; 252 | 253 | if(i < n - 1) 254 | { 255 | if(dump(",", 1, data) || 256 | dump_indent(flags, depth + 1, 1, dump, data)) 257 | goto array_error; 258 | } 259 | else 260 | { 261 | if(dump_indent(flags, depth, 0, dump, data)) 262 | goto array_error; 263 | } 264 | } 265 | 266 | array->visited = 0; 267 | return dump("]", 1, data); 268 | 269 | array_error: 270 | array->visited = 0; 271 | return -1; 272 | } 273 | 274 | case JSON_OBJECT: 275 | { 276 | json_object_t *object; 277 | void *iter; 278 | const char *separator; 279 | int separator_length; 280 | 281 | if(flags & JSON_COMPACT) { 282 | separator = ":"; 283 | separator_length = 1; 284 | } 285 | else { 286 | separator = ": "; 287 | separator_length = 2; 288 | } 289 | 290 | /* detect circular references */ 291 | object = json_to_object(json); 292 | if(object->visited) 293 | goto object_error; 294 | object->visited = 1; 295 | 296 | iter = json_object_iter((json_t *)json); 297 | 298 | if(dump("{", 1, data)) 299 | goto object_error; 300 | if(!iter) { 301 | object->visited = 0; 302 | return dump("}", 1, data); 303 | } 304 | if(dump_indent(flags, depth + 1, 0, dump, data)) 305 | goto object_error; 306 | 307 | if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER) 308 | { 309 | const object_key_t **keys; 310 | unsigned int size; 311 | unsigned int i; 312 | int (*cmp_func)(const void *, const void *); 313 | 314 | size = json_object_size(json); 315 | keys = malloc(size * sizeof(object_key_t *)); 316 | if(!keys) 317 | goto object_error; 318 | 319 | i = 0; 320 | while(iter) 321 | { 322 | keys[i] = jsonp_object_iter_fullkey(iter); 323 | iter = json_object_iter_next((json_t *)json, iter); 324 | i++; 325 | } 326 | assert(i == size); 327 | 328 | if(flags & JSON_SORT_KEYS) 329 | cmp_func = object_key_compare_keys; 330 | else 331 | cmp_func = object_key_compare_serials; 332 | 333 | qsort(keys, size, sizeof(object_key_t *), cmp_func); 334 | 335 | for(i = 0; i < size; i++) 336 | { 337 | const char *key; 338 | json_t *value; 339 | 340 | key = keys[i]->key; 341 | value = json_object_get(json, key); 342 | assert(value); 343 | 344 | dump_string(key, ascii, dump, data); 345 | if(dump(separator, separator_length, data) || 346 | do_dump(value, flags, depth + 1, dump, data)) 347 | { 348 | free(keys); 349 | goto object_error; 350 | } 351 | 352 | if(i < size - 1) 353 | { 354 | if(dump(",", 1, data) || 355 | dump_indent(flags, depth + 1, 1, dump, data)) 356 | { 357 | free(keys); 358 | goto object_error; 359 | } 360 | } 361 | else 362 | { 363 | if(dump_indent(flags, depth, 0, dump, data)) 364 | { 365 | free(keys); 366 | goto object_error; 367 | } 368 | } 369 | } 370 | 371 | free(keys); 372 | } 373 | else 374 | { 375 | /* Don't sort keys */ 376 | 377 | while(iter) 378 | { 379 | void *next = json_object_iter_next((json_t *)json, iter); 380 | 381 | dump_string(json_object_iter_key(iter), ascii, dump, data); 382 | if(dump(separator, separator_length, data) || 383 | do_dump(json_object_iter_value(iter), flags, depth + 1, 384 | dump, data)) 385 | goto object_error; 386 | 387 | if(next) 388 | { 389 | if(dump(",", 1, data) || 390 | dump_indent(flags, depth + 1, 1, dump, data)) 391 | goto object_error; 392 | } 393 | else 394 | { 395 | if(dump_indent(flags, depth, 0, dump, data)) 396 | goto object_error; 397 | } 398 | 399 | iter = next; 400 | } 401 | } 402 | 403 | object->visited = 0; 404 | return dump("}", 1, data); 405 | 406 | object_error: 407 | object->visited = 0; 408 | return -1; 409 | } 410 | 411 | default: 412 | /* not reached */ 413 | return -1; 414 | } 415 | } 416 | 417 | 418 | char *json_dumps(const json_t *json, unsigned long flags) 419 | { 420 | strbuffer_t strbuff; 421 | char *result; 422 | 423 | if(!json_is_array(json) && !json_is_object(json)) 424 | return NULL; 425 | 426 | if(strbuffer_init(&strbuff)) 427 | return NULL; 428 | 429 | if(do_dump(json, flags, 0, dump_to_strbuffer, (void *)&strbuff)) { 430 | strbuffer_close(&strbuff); 431 | return NULL; 432 | } 433 | 434 | result = strdup(strbuffer_value(&strbuff)); 435 | strbuffer_close(&strbuff); 436 | 437 | return result; 438 | } 439 | 440 | int json_dumpf(const json_t *json, FILE *output, unsigned long flags) 441 | { 442 | if(!json_is_array(json) && !json_is_object(json)) 443 | return -1; 444 | 445 | return do_dump(json, flags, 0, dump_to_file, (void *)output); 446 | } 447 | 448 | int json_dump_file(const json_t *json, const char *path, unsigned long flags) 449 | { 450 | int result; 451 | 452 | FILE *output = fopen(path, "w"); 453 | if(!output) 454 | return -1; 455 | 456 | result = json_dumpf(json, output, flags); 457 | 458 | fclose(output); 459 | return result; 460 | } 461 | -------------------------------------------------------------------------------- /sha2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 ArtForz 3 | * Copyright 2011-2013 pooler 4 | * 5 | * This program is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the Free 7 | * Software Foundation; either version 2 of the License, or (at your option) 8 | * any later version. See COPYING for more details. 9 | */ 10 | 11 | #include "cpuminer-config.h" 12 | #include "miner.h" 13 | 14 | #include 15 | #include 16 | 17 | #if defined(__arm__) && defined(__APCS_32__) 18 | #define EXTERN_SHA256 19 | #endif 20 | 21 | static const uint32_t sha256_h[8] = { 22 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 23 | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 24 | }; 25 | 26 | static const uint32_t sha256_k[64] = { 27 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 28 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 29 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 30 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 31 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 32 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 33 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 34 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 35 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 36 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 37 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 38 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 39 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 40 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 41 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 42 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 43 | }; 44 | 45 | void sha256_init(uint32_t *state) 46 | { 47 | memcpy(state, sha256_h, 32); 48 | } 49 | 50 | /* Elementary functions used by SHA256 */ 51 | #define Ch(x, y, z) ((x & (y ^ z)) ^ z) 52 | #define Maj(x, y, z) ((x & (y | z)) | (y & z)) 53 | #define ROTR(x, n) ((x >> n) | (x << (32 - n))) 54 | #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) 55 | #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) 56 | #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3)) 57 | #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10)) 58 | 59 | /* SHA256 round function */ 60 | #define RND(a, b, c, d, e, f, g, h, k) \ 61 | do { \ 62 | t0 = h + S1(e) + Ch(e, f, g) + k; \ 63 | t1 = S0(a) + Maj(a, b, c); \ 64 | d += t0; \ 65 | h = t0 + t1; \ 66 | } while (0) 67 | 68 | /* Adjusted round function for rotating state */ 69 | #define RNDr(S, W, i) \ 70 | RND(S[(64 - i) % 8], S[(65 - i) % 8], \ 71 | S[(66 - i) % 8], S[(67 - i) % 8], \ 72 | S[(68 - i) % 8], S[(69 - i) % 8], \ 73 | S[(70 - i) % 8], S[(71 - i) % 8], \ 74 | W[i] + sha256_k[i]) 75 | 76 | #ifndef EXTERN_SHA256 77 | 78 | /* 79 | * SHA256 block compression function. The 256-bit state is transformed via 80 | * the 512-bit input block to produce a new state. 81 | */ 82 | void sha256_transform(uint32_t *state, const uint32_t *block, int swap) 83 | { 84 | uint32_t W[64]; 85 | uint32_t S[8]; 86 | uint32_t t0, t1; 87 | int i; 88 | 89 | /* 1. Prepare message schedule W. */ 90 | if (swap) { 91 | for (i = 0; i < 16; i++) 92 | W[i] = swab32(block[i]); 93 | } else 94 | memcpy(W, block, 64); 95 | for (i = 16; i < 64; i += 2) { 96 | W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; 97 | W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; 98 | } 99 | 100 | /* 2. Initialize working variables. */ 101 | memcpy(S, state, 32); 102 | 103 | /* 3. Mix. */ 104 | RNDr(S, W, 0); 105 | RNDr(S, W, 1); 106 | RNDr(S, W, 2); 107 | RNDr(S, W, 3); 108 | RNDr(S, W, 4); 109 | RNDr(S, W, 5); 110 | RNDr(S, W, 6); 111 | RNDr(S, W, 7); 112 | RNDr(S, W, 8); 113 | RNDr(S, W, 9); 114 | RNDr(S, W, 10); 115 | RNDr(S, W, 11); 116 | RNDr(S, W, 12); 117 | RNDr(S, W, 13); 118 | RNDr(S, W, 14); 119 | RNDr(S, W, 15); 120 | RNDr(S, W, 16); 121 | RNDr(S, W, 17); 122 | RNDr(S, W, 18); 123 | RNDr(S, W, 19); 124 | RNDr(S, W, 20); 125 | RNDr(S, W, 21); 126 | RNDr(S, W, 22); 127 | RNDr(S, W, 23); 128 | RNDr(S, W, 24); 129 | RNDr(S, W, 25); 130 | RNDr(S, W, 26); 131 | RNDr(S, W, 27); 132 | RNDr(S, W, 28); 133 | RNDr(S, W, 29); 134 | RNDr(S, W, 30); 135 | RNDr(S, W, 31); 136 | RNDr(S, W, 32); 137 | RNDr(S, W, 33); 138 | RNDr(S, W, 34); 139 | RNDr(S, W, 35); 140 | RNDr(S, W, 36); 141 | RNDr(S, W, 37); 142 | RNDr(S, W, 38); 143 | RNDr(S, W, 39); 144 | RNDr(S, W, 40); 145 | RNDr(S, W, 41); 146 | RNDr(S, W, 42); 147 | RNDr(S, W, 43); 148 | RNDr(S, W, 44); 149 | RNDr(S, W, 45); 150 | RNDr(S, W, 46); 151 | RNDr(S, W, 47); 152 | RNDr(S, W, 48); 153 | RNDr(S, W, 49); 154 | RNDr(S, W, 50); 155 | RNDr(S, W, 51); 156 | RNDr(S, W, 52); 157 | RNDr(S, W, 53); 158 | RNDr(S, W, 54); 159 | RNDr(S, W, 55); 160 | RNDr(S, W, 56); 161 | RNDr(S, W, 57); 162 | RNDr(S, W, 58); 163 | RNDr(S, W, 59); 164 | RNDr(S, W, 60); 165 | RNDr(S, W, 61); 166 | RNDr(S, W, 62); 167 | RNDr(S, W, 63); 168 | 169 | /* 4. Mix local working variables into global state */ 170 | for (i = 0; i < 8; i++) 171 | state[i] += S[i]; 172 | } 173 | 174 | #endif /* EXTERN_SHA256 */ 175 | 176 | 177 | static const uint32_t sha256d_hash1[16] = { 178 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 179 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 180 | 0x80000000, 0x00000000, 0x00000000, 0x00000000, 181 | 0x00000000, 0x00000000, 0x00000000, 0x00000100 182 | }; 183 | 184 | static void sha256d_80_swap(uint32_t *hash, const uint32_t *data) 185 | { 186 | uint32_t S[16]; 187 | int i; 188 | 189 | sha256_init(S); 190 | sha256_transform(S, data, 0); 191 | sha256_transform(S, data + 16, 0); 192 | memcpy(S + 8, sha256d_hash1 + 8, 32); 193 | sha256_init(hash); 194 | sha256_transform(hash, S, 0); 195 | for (i = 0; i < 8; i++) 196 | hash[i] = swab32(hash[i]); 197 | } 198 | 199 | void sha256d(unsigned char *hash, const unsigned char *data, int len) 200 | { 201 | uint32_t S[16], T[16]; 202 | int i, r; 203 | 204 | sha256_init(S); 205 | for (r = len; r > -9; r -= 64) { 206 | if (r < 64) 207 | memset(T, 0, 64); 208 | memcpy(T, data + len - r, r > 64 ? 64 : (r < 0 ? 0 : r)); 209 | if (r >= 0 && r < 64) 210 | ((unsigned char *)T)[r] = 0x80; 211 | for (i = 0; i < 16; i++) 212 | T[i] = be32dec(T + i); 213 | if (r < 56) 214 | T[15] = 8 * len; 215 | sha256_transform(S, T, 0); 216 | } 217 | memcpy(S + 8, sha256d_hash1 + 8, 32); 218 | sha256_init(T); 219 | sha256_transform(T, S, 0); 220 | for (i = 0; i < 8; i++) 221 | be32enc((uint32_t *)hash + i, T[i]); 222 | } 223 | 224 | static inline void sha256d_preextend(uint32_t *W) 225 | { 226 | W[16] = s1(W[14]) + W[ 9] + s0(W[ 1]) + W[ 0]; 227 | W[17] = s1(W[15]) + W[10] + s0(W[ 2]) + W[ 1]; 228 | W[18] = s1(W[16]) + W[11] + W[ 2]; 229 | W[19] = s1(W[17]) + W[12] + s0(W[ 4]); 230 | W[20] = W[13] + s0(W[ 5]) + W[ 4]; 231 | W[21] = W[14] + s0(W[ 6]) + W[ 5]; 232 | W[22] = W[15] + s0(W[ 7]) + W[ 6]; 233 | W[23] = W[16] + s0(W[ 8]) + W[ 7]; 234 | W[24] = W[17] + s0(W[ 9]) + W[ 8]; 235 | W[25] = s0(W[10]) + W[ 9]; 236 | W[26] = s0(W[11]) + W[10]; 237 | W[27] = s0(W[12]) + W[11]; 238 | W[28] = s0(W[13]) + W[12]; 239 | W[29] = s0(W[14]) + W[13]; 240 | W[30] = s0(W[15]) + W[14]; 241 | W[31] = s0(W[16]) + W[15]; 242 | } 243 | 244 | static inline void sha256d_prehash(uint32_t *S, const uint32_t *W) 245 | { 246 | uint32_t t0, t1; 247 | RNDr(S, W, 0); 248 | RNDr(S, W, 1); 249 | RNDr(S, W, 2); 250 | } 251 | 252 | #ifdef EXTERN_SHA256 253 | 254 | void sha256d_ms(uint32_t *hash, uint32_t *W, 255 | const uint32_t *midstate, const uint32_t *prehash); 256 | 257 | #else 258 | 259 | static inline void sha256d_ms(uint32_t *hash, uint32_t *W, 260 | const uint32_t *midstate, const uint32_t *prehash) 261 | { 262 | uint32_t S[64]; 263 | uint32_t t0, t1; 264 | int i; 265 | 266 | S[18] = W[18]; 267 | S[19] = W[19]; 268 | S[20] = W[20]; 269 | S[22] = W[22]; 270 | S[23] = W[23]; 271 | S[24] = W[24]; 272 | S[30] = W[30]; 273 | S[31] = W[31]; 274 | 275 | W[18] += s0(W[3]); 276 | W[19] += W[3]; 277 | W[20] += s1(W[18]); 278 | W[21] = s1(W[19]); 279 | W[22] += s1(W[20]); 280 | W[23] += s1(W[21]); 281 | W[24] += s1(W[22]); 282 | W[25] = s1(W[23]) + W[18]; 283 | W[26] = s1(W[24]) + W[19]; 284 | W[27] = s1(W[25]) + W[20]; 285 | W[28] = s1(W[26]) + W[21]; 286 | W[29] = s1(W[27]) + W[22]; 287 | W[30] += s1(W[28]) + W[23]; 288 | W[31] += s1(W[29]) + W[24]; 289 | for (i = 32; i < 64; i += 2) { 290 | W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; 291 | W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; 292 | } 293 | 294 | memcpy(S, prehash, 32); 295 | 296 | RNDr(S, W, 3); 297 | RNDr(S, W, 4); 298 | RNDr(S, W, 5); 299 | RNDr(S, W, 6); 300 | RNDr(S, W, 7); 301 | RNDr(S, W, 8); 302 | RNDr(S, W, 9); 303 | RNDr(S, W, 10); 304 | RNDr(S, W, 11); 305 | RNDr(S, W, 12); 306 | RNDr(S, W, 13); 307 | RNDr(S, W, 14); 308 | RNDr(S, W, 15); 309 | RNDr(S, W, 16); 310 | RNDr(S, W, 17); 311 | RNDr(S, W, 18); 312 | RNDr(S, W, 19); 313 | RNDr(S, W, 20); 314 | RNDr(S, W, 21); 315 | RNDr(S, W, 22); 316 | RNDr(S, W, 23); 317 | RNDr(S, W, 24); 318 | RNDr(S, W, 25); 319 | RNDr(S, W, 26); 320 | RNDr(S, W, 27); 321 | RNDr(S, W, 28); 322 | RNDr(S, W, 29); 323 | RNDr(S, W, 30); 324 | RNDr(S, W, 31); 325 | RNDr(S, W, 32); 326 | RNDr(S, W, 33); 327 | RNDr(S, W, 34); 328 | RNDr(S, W, 35); 329 | RNDr(S, W, 36); 330 | RNDr(S, W, 37); 331 | RNDr(S, W, 38); 332 | RNDr(S, W, 39); 333 | RNDr(S, W, 40); 334 | RNDr(S, W, 41); 335 | RNDr(S, W, 42); 336 | RNDr(S, W, 43); 337 | RNDr(S, W, 44); 338 | RNDr(S, W, 45); 339 | RNDr(S, W, 46); 340 | RNDr(S, W, 47); 341 | RNDr(S, W, 48); 342 | RNDr(S, W, 49); 343 | RNDr(S, W, 50); 344 | RNDr(S, W, 51); 345 | RNDr(S, W, 52); 346 | RNDr(S, W, 53); 347 | RNDr(S, W, 54); 348 | RNDr(S, W, 55); 349 | RNDr(S, W, 56); 350 | RNDr(S, W, 57); 351 | RNDr(S, W, 58); 352 | RNDr(S, W, 59); 353 | RNDr(S, W, 60); 354 | RNDr(S, W, 61); 355 | RNDr(S, W, 62); 356 | RNDr(S, W, 63); 357 | 358 | for (i = 0; i < 8; i++) 359 | S[i] += midstate[i]; 360 | 361 | W[18] = S[18]; 362 | W[19] = S[19]; 363 | W[20] = S[20]; 364 | W[22] = S[22]; 365 | W[23] = S[23]; 366 | W[24] = S[24]; 367 | W[30] = S[30]; 368 | W[31] = S[31]; 369 | 370 | memcpy(S + 8, sha256d_hash1 + 8, 32); 371 | S[16] = s1(sha256d_hash1[14]) + sha256d_hash1[ 9] + s0(S[ 1]) + S[ 0]; 372 | S[17] = s1(sha256d_hash1[15]) + sha256d_hash1[10] + s0(S[ 2]) + S[ 1]; 373 | S[18] = s1(S[16]) + sha256d_hash1[11] + s0(S[ 3]) + S[ 2]; 374 | S[19] = s1(S[17]) + sha256d_hash1[12] + s0(S[ 4]) + S[ 3]; 375 | S[20] = s1(S[18]) + sha256d_hash1[13] + s0(S[ 5]) + S[ 4]; 376 | S[21] = s1(S[19]) + sha256d_hash1[14] + s0(S[ 6]) + S[ 5]; 377 | S[22] = s1(S[20]) + sha256d_hash1[15] + s0(S[ 7]) + S[ 6]; 378 | S[23] = s1(S[21]) + S[16] + s0(sha256d_hash1[ 8]) + S[ 7]; 379 | S[24] = s1(S[22]) + S[17] + s0(sha256d_hash1[ 9]) + sha256d_hash1[ 8]; 380 | S[25] = s1(S[23]) + S[18] + s0(sha256d_hash1[10]) + sha256d_hash1[ 9]; 381 | S[26] = s1(S[24]) + S[19] + s0(sha256d_hash1[11]) + sha256d_hash1[10]; 382 | S[27] = s1(S[25]) + S[20] + s0(sha256d_hash1[12]) + sha256d_hash1[11]; 383 | S[28] = s1(S[26]) + S[21] + s0(sha256d_hash1[13]) + sha256d_hash1[12]; 384 | S[29] = s1(S[27]) + S[22] + s0(sha256d_hash1[14]) + sha256d_hash1[13]; 385 | S[30] = s1(S[28]) + S[23] + s0(sha256d_hash1[15]) + sha256d_hash1[14]; 386 | S[31] = s1(S[29]) + S[24] + s0(S[16]) + sha256d_hash1[15]; 387 | for (i = 32; i < 60; i += 2) { 388 | S[i] = s1(S[i - 2]) + S[i - 7] + s0(S[i - 15]) + S[i - 16]; 389 | S[i+1] = s1(S[i - 1]) + S[i - 6] + s0(S[i - 14]) + S[i - 15]; 390 | } 391 | S[60] = s1(S[58]) + S[53] + s0(S[45]) + S[44]; 392 | 393 | sha256_init(hash); 394 | 395 | RNDr(hash, S, 0); 396 | RNDr(hash, S, 1); 397 | RNDr(hash, S, 2); 398 | RNDr(hash, S, 3); 399 | RNDr(hash, S, 4); 400 | RNDr(hash, S, 5); 401 | RNDr(hash, S, 6); 402 | RNDr(hash, S, 7); 403 | RNDr(hash, S, 8); 404 | RNDr(hash, S, 9); 405 | RNDr(hash, S, 10); 406 | RNDr(hash, S, 11); 407 | RNDr(hash, S, 12); 408 | RNDr(hash, S, 13); 409 | RNDr(hash, S, 14); 410 | RNDr(hash, S, 15); 411 | RNDr(hash, S, 16); 412 | RNDr(hash, S, 17); 413 | RNDr(hash, S, 18); 414 | RNDr(hash, S, 19); 415 | RNDr(hash, S, 20); 416 | RNDr(hash, S, 21); 417 | RNDr(hash, S, 22); 418 | RNDr(hash, S, 23); 419 | RNDr(hash, S, 24); 420 | RNDr(hash, S, 25); 421 | RNDr(hash, S, 26); 422 | RNDr(hash, S, 27); 423 | RNDr(hash, S, 28); 424 | RNDr(hash, S, 29); 425 | RNDr(hash, S, 30); 426 | RNDr(hash, S, 31); 427 | RNDr(hash, S, 32); 428 | RNDr(hash, S, 33); 429 | RNDr(hash, S, 34); 430 | RNDr(hash, S, 35); 431 | RNDr(hash, S, 36); 432 | RNDr(hash, S, 37); 433 | RNDr(hash, S, 38); 434 | RNDr(hash, S, 39); 435 | RNDr(hash, S, 40); 436 | RNDr(hash, S, 41); 437 | RNDr(hash, S, 42); 438 | RNDr(hash, S, 43); 439 | RNDr(hash, S, 44); 440 | RNDr(hash, S, 45); 441 | RNDr(hash, S, 46); 442 | RNDr(hash, S, 47); 443 | RNDr(hash, S, 48); 444 | RNDr(hash, S, 49); 445 | RNDr(hash, S, 50); 446 | RNDr(hash, S, 51); 447 | RNDr(hash, S, 52); 448 | RNDr(hash, S, 53); 449 | RNDr(hash, S, 54); 450 | RNDr(hash, S, 55); 451 | RNDr(hash, S, 56); 452 | 453 | hash[2] += hash[6] + S1(hash[3]) + Ch(hash[3], hash[4], hash[5]) 454 | + S[57] + sha256_k[57]; 455 | hash[1] += hash[5] + S1(hash[2]) + Ch(hash[2], hash[3], hash[4]) 456 | + S[58] + sha256_k[58]; 457 | hash[0] += hash[4] + S1(hash[1]) + Ch(hash[1], hash[2], hash[3]) 458 | + S[59] + sha256_k[59]; 459 | hash[7] += hash[3] + S1(hash[0]) + Ch(hash[0], hash[1], hash[2]) 460 | + S[60] + sha256_k[60] 461 | + sha256_h[7]; 462 | } 463 | 464 | #endif /* EXTERN_SHA256 */ 465 | 466 | #ifdef HAVE_SHA256_4WAY 467 | 468 | void sha256d_ms_4way(uint32_t *hash, uint32_t *data, 469 | const uint32_t *midstate, const uint32_t *prehash); 470 | 471 | static inline int scanhash_sha256d_4way(int thr_id, uint32_t *pdata, 472 | const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) 473 | { 474 | uint32_t data[4 * 64] __attribute__((aligned(128))); 475 | uint32_t hash[4 * 8] __attribute__((aligned(32))); 476 | uint32_t midstate[4 * 8] __attribute__((aligned(32))); 477 | uint32_t prehash[4 * 8] __attribute__((aligned(32))); 478 | uint32_t n = pdata[19] - 1; 479 | const uint32_t first_nonce = pdata[19]; 480 | const uint32_t Htarg = ptarget[7]; 481 | int i, j; 482 | 483 | memcpy(data, pdata + 16, 64); 484 | sha256d_preextend(data); 485 | for (i = 31; i >= 0; i--) 486 | for (j = 0; j < 4; j++) 487 | data[i * 4 + j] = data[i]; 488 | 489 | sha256_init(midstate); 490 | sha256_transform(midstate, pdata, 0); 491 | memcpy(prehash, midstate, 32); 492 | sha256d_prehash(prehash, pdata + 16); 493 | for (i = 7; i >= 0; i--) { 494 | for (j = 0; j < 4; j++) { 495 | midstate[i * 4 + j] = midstate[i]; 496 | prehash[i * 4 + j] = prehash[i]; 497 | } 498 | } 499 | 500 | do { 501 | for (i = 0; i < 4; i++) 502 | data[4 * 3 + i] = ++n; 503 | 504 | sha256d_ms_4way(hash, data, midstate, prehash); 505 | 506 | for (i = 0; i < 4; i++) { 507 | if (swab32(hash[4 * 7 + i]) <= Htarg) { 508 | pdata[19] = data[4 * 3 + i]; 509 | sha256d_80_swap(hash, pdata); 510 | if (fulltest(hash, ptarget)) { 511 | *hashes_done = n - first_nonce + 1; 512 | return 1; 513 | } 514 | } 515 | } 516 | } while (n < max_nonce && !work_restart[thr_id].restart); 517 | 518 | *hashes_done = n - first_nonce + 1; 519 | pdata[19] = n; 520 | return 0; 521 | } 522 | 523 | #endif /* HAVE_SHA256_4WAY */ 524 | 525 | #ifdef HAVE_SHA256_8WAY 526 | 527 | void sha256d_ms_8way(uint32_t *hash, uint32_t *data, 528 | const uint32_t *midstate, const uint32_t *prehash); 529 | 530 | static inline int scanhash_sha256d_8way(int thr_id, uint32_t *pdata, 531 | const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) 532 | { 533 | uint32_t data[8 * 64] __attribute__((aligned(128))); 534 | uint32_t hash[8 * 8] __attribute__((aligned(32))); 535 | uint32_t midstate[8 * 8] __attribute__((aligned(32))); 536 | uint32_t prehash[8 * 8] __attribute__((aligned(32))); 537 | uint32_t n = pdata[19] - 1; 538 | const uint32_t first_nonce = pdata[19]; 539 | const uint32_t Htarg = ptarget[7]; 540 | int i, j; 541 | 542 | memcpy(data, pdata + 16, 64); 543 | sha256d_preextend(data); 544 | for (i = 31; i >= 0; i--) 545 | for (j = 0; j < 8; j++) 546 | data[i * 8 + j] = data[i]; 547 | 548 | sha256_init(midstate); 549 | sha256_transform(midstate, pdata, 0); 550 | memcpy(prehash, midstate, 32); 551 | sha256d_prehash(prehash, pdata + 16); 552 | for (i = 7; i >= 0; i--) { 553 | for (j = 0; j < 8; j++) { 554 | midstate[i * 8 + j] = midstate[i]; 555 | prehash[i * 8 + j] = prehash[i]; 556 | } 557 | } 558 | 559 | do { 560 | for (i = 0; i < 8; i++) 561 | data[8 * 3 + i] = ++n; 562 | 563 | sha256d_ms_8way(hash, data, midstate, prehash); 564 | 565 | for (i = 0; i < 8; i++) { 566 | if (swab32(hash[8 * 7 + i]) <= Htarg) { 567 | pdata[19] = data[8 * 3 + i]; 568 | sha256d_80_swap(hash, pdata); 569 | if (fulltest(hash, ptarget)) { 570 | *hashes_done = n - first_nonce + 1; 571 | return 1; 572 | } 573 | } 574 | } 575 | } while (n < max_nonce && !work_restart[thr_id].restart); 576 | 577 | *hashes_done = n - first_nonce + 1; 578 | pdata[19] = n; 579 | return 0; 580 | } 581 | 582 | #endif /* HAVE_SHA256_8WAY */ 583 | 584 | int scanhash_sha256d(int thr_id, uint32_t *pdata, const uint32_t *ptarget, 585 | uint32_t max_nonce, unsigned long *hashes_done) 586 | { 587 | uint32_t data[64] __attribute__((aligned(128))); 588 | uint32_t hash[8] __attribute__((aligned(32))); 589 | uint32_t midstate[8] __attribute__((aligned(32))); 590 | uint32_t prehash[8] __attribute__((aligned(32))); 591 | uint32_t n = pdata[19] - 1; 592 | const uint32_t first_nonce = pdata[19]; 593 | const uint32_t Htarg = ptarget[7]; 594 | 595 | #ifdef HAVE_SHA256_8WAY 596 | if (sha256_use_8way()) 597 | return scanhash_sha256d_8way(thr_id, pdata, ptarget, 598 | max_nonce, hashes_done); 599 | #endif 600 | #ifdef HAVE_SHA256_4WAY 601 | if (sha256_use_4way()) 602 | return scanhash_sha256d_4way(thr_id, pdata, ptarget, 603 | max_nonce, hashes_done); 604 | #endif 605 | 606 | memcpy(data, pdata + 16, 64); 607 | sha256d_preextend(data); 608 | 609 | sha256_init(midstate); 610 | sha256_transform(midstate, pdata, 0); 611 | memcpy(prehash, midstate, 32); 612 | sha256d_prehash(prehash, pdata + 16); 613 | 614 | do { 615 | data[3] = ++n; 616 | sha256d_ms(hash, data, midstate, prehash); 617 | if (swab32(hash[7]) <= Htarg) { 618 | pdata[19] = data[3]; 619 | sha256d_80_swap(hash, pdata); 620 | if (fulltest(hash, ptarget)) { 621 | *hashes_done = n - first_nonce + 1; 622 | return 1; 623 | } 624 | } 625 | } while (n < max_nonce && !work_restart[thr_id].restart); 626 | 627 | *hashes_done = n - first_nonce + 1; 628 | pdata[19] = n; 629 | return 0; 630 | } 631 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /scrypt-x86.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2012 pooler@litecoinpool.org 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | */ 26 | 27 | #include "cpuminer-config.h" 28 | 29 | #if defined(__linux__) && defined(__ELF__) 30 | .section .note.GNU-stack,"",%progbits 31 | #endif 32 | 33 | #if defined(__i386__) 34 | 35 | .macro scrypt_shuffle src, so, dest, do 36 | movl \so+60(\src), %eax 37 | movl \so+44(\src), %ebx 38 | movl \so+28(\src), %ecx 39 | movl \so+12(\src), %edx 40 | movl %eax, \do+12(\dest) 41 | movl %ebx, \do+28(\dest) 42 | movl %ecx, \do+44(\dest) 43 | movl %edx, \do+60(\dest) 44 | movl \so+40(\src), %eax 45 | movl \so+8(\src), %ebx 46 | movl \so+48(\src), %ecx 47 | movl \so+16(\src), %edx 48 | movl %eax, \do+8(\dest) 49 | movl %ebx, \do+40(\dest) 50 | movl %ecx, \do+16(\dest) 51 | movl %edx, \do+48(\dest) 52 | movl \so+20(\src), %eax 53 | movl \so+4(\src), %ebx 54 | movl \so+52(\src), %ecx 55 | movl \so+36(\src), %edx 56 | movl %eax, \do+4(\dest) 57 | movl %ebx, \do+20(\dest) 58 | movl %ecx, \do+36(\dest) 59 | movl %edx, \do+52(\dest) 60 | movl \so+0(\src), %eax 61 | movl \so+24(\src), %ebx 62 | movl \so+32(\src), %ecx 63 | movl \so+56(\src), %edx 64 | movl %eax, \do+0(\dest) 65 | movl %ebx, \do+24(\dest) 66 | movl %ecx, \do+32(\dest) 67 | movl %edx, \do+56(\dest) 68 | .endm 69 | 70 | .macro salsa8_core_gen_quadround 71 | movl 52(%esp), %ecx 72 | movl 4(%esp), %edx 73 | movl 20(%esp), %ebx 74 | movl 8(%esp), %esi 75 | leal (%ecx, %edx), %edi 76 | roll $7, %edi 77 | xorl %edi, %ebx 78 | movl %ebx, 4(%esp) 79 | movl 36(%esp), %edi 80 | leal (%edx, %ebx), %ebp 81 | roll $9, %ebp 82 | xorl %ebp, %edi 83 | movl 24(%esp), %ebp 84 | movl %edi, 8(%esp) 85 | addl %edi, %ebx 86 | roll $13, %ebx 87 | xorl %ebx, %ecx 88 | movl 40(%esp), %ebx 89 | movl %ecx, 20(%esp) 90 | addl %edi, %ecx 91 | roll $18, %ecx 92 | leal (%esi, %ebp), %edi 93 | roll $7, %edi 94 | xorl %edi, %ebx 95 | movl %ebx, 24(%esp) 96 | movl 56(%esp), %edi 97 | xorl %ecx, %edx 98 | leal (%ebp, %ebx), %ecx 99 | roll $9, %ecx 100 | xorl %ecx, %edi 101 | movl %edi, 36(%esp) 102 | movl 28(%esp), %ecx 103 | movl %edx, 28(%esp) 104 | movl 44(%esp), %edx 105 | addl %edi, %ebx 106 | roll $13, %ebx 107 | xorl %ebx, %esi 108 | movl 60(%esp), %ebx 109 | movl %esi, 40(%esp) 110 | addl %edi, %esi 111 | roll $18, %esi 112 | leal (%ecx, %edx), %edi 113 | roll $7, %edi 114 | xorl %edi, %ebx 115 | movl %ebx, 44(%esp) 116 | movl 12(%esp), %edi 117 | xorl %esi, %ebp 118 | leal (%edx, %ebx), %esi 119 | roll $9, %esi 120 | xorl %esi, %edi 121 | movl %edi, 12(%esp) 122 | movl 48(%esp), %esi 123 | movl %ebp, 48(%esp) 124 | movl 64(%esp), %ebp 125 | addl %edi, %ebx 126 | roll $13, %ebx 127 | xorl %ebx, %ecx 128 | movl 16(%esp), %ebx 129 | movl %ecx, 16(%esp) 130 | addl %edi, %ecx 131 | roll $18, %ecx 132 | leal (%esi, %ebp), %edi 133 | roll $7, %edi 134 | xorl %edi, %ebx 135 | movl 32(%esp), %edi 136 | xorl %ecx, %edx 137 | leal (%ebp, %ebx), %ecx 138 | roll $9, %ecx 139 | xorl %ecx, %edi 140 | movl %edi, 32(%esp) 141 | movl %ebx, %ecx 142 | movl %edx, 52(%esp) 143 | movl 28(%esp), %edx 144 | addl %edi, %ebx 145 | roll $13, %ebx 146 | xorl %ebx, %esi 147 | movl 40(%esp), %ebx 148 | movl %esi, 28(%esp) 149 | addl %edi, %esi 150 | roll $18, %esi 151 | leal (%ecx, %edx), %edi 152 | roll $7, %edi 153 | xorl %edi, %ebx 154 | movl %ebx, 40(%esp) 155 | movl 12(%esp), %edi 156 | xorl %esi, %ebp 157 | leal (%edx, %ebx), %esi 158 | roll $9, %esi 159 | xorl %esi, %edi 160 | movl %edi, 12(%esp) 161 | movl 4(%esp), %esi 162 | movl %ebp, 4(%esp) 163 | movl 48(%esp), %ebp 164 | addl %edi, %ebx 165 | roll $13, %ebx 166 | xorl %ebx, %ecx 167 | movl 16(%esp), %ebx 168 | movl %ecx, 16(%esp) 169 | addl %edi, %ecx 170 | roll $18, %ecx 171 | leal (%esi, %ebp), %edi 172 | roll $7, %edi 173 | xorl %edi, %ebx 174 | movl %ebx, 48(%esp) 175 | movl 32(%esp), %edi 176 | xorl %ecx, %edx 177 | leal (%ebp, %ebx), %ecx 178 | roll $9, %ecx 179 | xorl %ecx, %edi 180 | movl %edi, 32(%esp) 181 | movl 24(%esp), %ecx 182 | movl %edx, 24(%esp) 183 | movl 52(%esp), %edx 184 | addl %edi, %ebx 185 | roll $13, %ebx 186 | xorl %ebx, %esi 187 | movl 28(%esp), %ebx 188 | movl %esi, 28(%esp) 189 | addl %edi, %esi 190 | roll $18, %esi 191 | leal (%ecx, %edx), %edi 192 | roll $7, %edi 193 | xorl %edi, %ebx 194 | movl %ebx, 52(%esp) 195 | movl 8(%esp), %edi 196 | xorl %esi, %ebp 197 | leal (%edx, %ebx), %esi 198 | roll $9, %esi 199 | xorl %esi, %edi 200 | movl %edi, 8(%esp) 201 | movl 44(%esp), %esi 202 | movl %ebp, 44(%esp) 203 | movl 4(%esp), %ebp 204 | addl %edi, %ebx 205 | roll $13, %ebx 206 | xorl %ebx, %ecx 207 | movl 20(%esp), %ebx 208 | movl %ecx, 4(%esp) 209 | addl %edi, %ecx 210 | roll $18, %ecx 211 | leal (%esi, %ebp), %edi 212 | roll $7, %edi 213 | xorl %edi, %ebx 214 | movl 36(%esp), %edi 215 | xorl %ecx, %edx 216 | leal (%ebp, %ebx), %ecx 217 | roll $9, %ecx 218 | xorl %ecx, %edi 219 | movl %edi, 20(%esp) 220 | movl %ebx, %ecx 221 | movl %edx, 36(%esp) 222 | movl 24(%esp), %edx 223 | addl %edi, %ebx 224 | roll $13, %ebx 225 | xorl %ebx, %esi 226 | movl 28(%esp), %ebx 227 | movl %esi, 24(%esp) 228 | addl %edi, %esi 229 | roll $18, %esi 230 | leal (%ecx, %edx), %edi 231 | roll $7, %edi 232 | xorl %edi, %ebx 233 | movl %ebx, 28(%esp) 234 | xorl %esi, %ebp 235 | movl 8(%esp), %esi 236 | leal (%edx, %ebx), %edi 237 | roll $9, %edi 238 | xorl %edi, %esi 239 | movl 40(%esp), %edi 240 | movl %ebp, 8(%esp) 241 | movl 44(%esp), %ebp 242 | movl %esi, 40(%esp) 243 | addl %esi, %ebx 244 | roll $13, %ebx 245 | xorl %ebx, %ecx 246 | movl 4(%esp), %ebx 247 | movl %ecx, 44(%esp) 248 | addl %esi, %ecx 249 | roll $18, %ecx 250 | leal (%edi, %ebp), %esi 251 | roll $7, %esi 252 | xorl %esi, %ebx 253 | movl %ebx, 4(%esp) 254 | movl 20(%esp), %esi 255 | xorl %ecx, %edx 256 | leal (%ebp, %ebx), %ecx 257 | roll $9, %ecx 258 | xorl %ecx, %esi 259 | movl %esi, 56(%esp) 260 | movl 48(%esp), %ecx 261 | movl %edx, 20(%esp) 262 | movl 36(%esp), %edx 263 | addl %esi, %ebx 264 | roll $13, %ebx 265 | xorl %ebx, %edi 266 | movl 24(%esp), %ebx 267 | movl %edi, 24(%esp) 268 | addl %esi, %edi 269 | roll $18, %edi 270 | leal (%ecx, %edx), %esi 271 | roll $7, %esi 272 | xorl %esi, %ebx 273 | movl %ebx, 60(%esp) 274 | movl 12(%esp), %esi 275 | xorl %edi, %ebp 276 | leal (%edx, %ebx), %edi 277 | roll $9, %edi 278 | xorl %edi, %esi 279 | movl %esi, 12(%esp) 280 | movl 52(%esp), %edi 281 | movl %ebp, 36(%esp) 282 | movl 8(%esp), %ebp 283 | addl %esi, %ebx 284 | roll $13, %ebx 285 | xorl %ebx, %ecx 286 | movl 16(%esp), %ebx 287 | movl %ecx, 16(%esp) 288 | addl %esi, %ecx 289 | roll $18, %ecx 290 | leal (%edi, %ebp), %esi 291 | roll $7, %esi 292 | xorl %esi, %ebx 293 | movl 32(%esp), %esi 294 | xorl %ecx, %edx 295 | leal (%ebp, %ebx), %ecx 296 | roll $9, %ecx 297 | xorl %ecx, %esi 298 | movl %esi, 32(%esp) 299 | movl %ebx, %ecx 300 | movl %edx, 48(%esp) 301 | movl 20(%esp), %edx 302 | addl %esi, %ebx 303 | roll $13, %ebx 304 | xorl %ebx, %edi 305 | movl 24(%esp), %ebx 306 | movl %edi, 20(%esp) 307 | addl %esi, %edi 308 | roll $18, %edi 309 | leal (%ecx, %edx), %esi 310 | roll $7, %esi 311 | xorl %esi, %ebx 312 | movl %ebx, 8(%esp) 313 | movl 12(%esp), %esi 314 | xorl %edi, %ebp 315 | leal (%edx, %ebx), %edi 316 | roll $9, %edi 317 | xorl %edi, %esi 318 | movl %esi, 12(%esp) 319 | movl 28(%esp), %edi 320 | movl %ebp, 52(%esp) 321 | movl 36(%esp), %ebp 322 | addl %esi, %ebx 323 | roll $13, %ebx 324 | xorl %ebx, %ecx 325 | movl 16(%esp), %ebx 326 | movl %ecx, 16(%esp) 327 | addl %esi, %ecx 328 | roll $18, %ecx 329 | leal (%edi, %ebp), %esi 330 | roll $7, %esi 331 | xorl %esi, %ebx 332 | movl %ebx, 28(%esp) 333 | movl 32(%esp), %esi 334 | xorl %ecx, %edx 335 | leal (%ebp, %ebx), %ecx 336 | roll $9, %ecx 337 | xorl %ecx, %esi 338 | movl %esi, 32(%esp) 339 | movl 4(%esp), %ecx 340 | movl %edx, 4(%esp) 341 | movl 48(%esp), %edx 342 | addl %esi, %ebx 343 | roll $13, %ebx 344 | xorl %ebx, %edi 345 | movl 20(%esp), %ebx 346 | movl %edi, 20(%esp) 347 | addl %esi, %edi 348 | roll $18, %edi 349 | leal (%ecx, %edx), %esi 350 | roll $7, %esi 351 | xorl %esi, %ebx 352 | movl %ebx, 48(%esp) 353 | movl 40(%esp), %esi 354 | xorl %edi, %ebp 355 | leal (%edx, %ebx), %edi 356 | roll $9, %edi 357 | xorl %edi, %esi 358 | movl %esi, 36(%esp) 359 | movl 60(%esp), %edi 360 | movl %ebp, 24(%esp) 361 | movl 52(%esp), %ebp 362 | addl %esi, %ebx 363 | roll $13, %ebx 364 | xorl %ebx, %ecx 365 | movl 44(%esp), %ebx 366 | movl %ecx, 40(%esp) 367 | addl %esi, %ecx 368 | roll $18, %ecx 369 | leal (%edi, %ebp), %esi 370 | roll $7, %esi 371 | xorl %esi, %ebx 372 | movl %ebx, 52(%esp) 373 | movl 56(%esp), %esi 374 | xorl %ecx, %edx 375 | leal (%ebp, %ebx), %ecx 376 | roll $9, %ecx 377 | xorl %ecx, %esi 378 | movl %esi, 56(%esp) 379 | addl %esi, %ebx 380 | movl %edx, 44(%esp) 381 | roll $13, %ebx 382 | xorl %ebx, %edi 383 | movl %edi, 60(%esp) 384 | addl %esi, %edi 385 | roll $18, %edi 386 | xorl %edi, %ebp 387 | movl %ebp, 64(%esp) 388 | .endm 389 | 390 | .text 391 | .p2align 5 392 | salsa8_core_gen: 393 | salsa8_core_gen_quadround 394 | salsa8_core_gen_quadround 395 | ret 396 | 397 | 398 | .text 399 | .p2align 5 400 | .globl scrypt_core 401 | .globl _scrypt_core 402 | scrypt_core: 403 | _scrypt_core: 404 | pushl %ebx 405 | pushl %ebp 406 | pushl %edi 407 | pushl %esi 408 | 409 | /* Check for SSE2 availability */ 410 | movl $1, %eax 411 | cpuid 412 | andl $0x04000000, %edx 413 | jnz scrypt_core_sse2 414 | 415 | scrypt_core_gen: 416 | movl 20(%esp), %edi 417 | movl 24(%esp), %esi 418 | subl $72, %esp 419 | 420 | .macro scrypt_core_macro1a p, q 421 | movl \p(%edi), %eax 422 | movl \q(%edi), %edx 423 | movl %eax, \p(%esi) 424 | movl %edx, \q(%esi) 425 | xorl %edx, %eax 426 | movl %eax, \p(%edi) 427 | movl %eax, \p(%esp) 428 | .endm 429 | 430 | .macro scrypt_core_macro1b p, q 431 | movl \p(%edi), %eax 432 | xorl \p(%esi, %edx), %eax 433 | movl \q(%edi), %ebx 434 | xorl \q(%esi, %edx), %ebx 435 | movl %ebx, \q(%edi) 436 | xorl %ebx, %eax 437 | movl %eax, \p(%edi) 438 | movl %eax, \p(%esp) 439 | .endm 440 | 441 | .macro scrypt_core_macro2 p, q 442 | movl \p(%esp), %eax 443 | addl \p(%edi), %eax 444 | movl %eax, \p(%edi) 445 | xorl \q(%edi), %eax 446 | movl %eax, \q(%edi) 447 | movl %eax, \p(%esp) 448 | .endm 449 | 450 | .macro scrypt_core_macro3 p, q 451 | movl \p(%esp), %eax 452 | addl \q(%edi), %eax 453 | movl %eax, \q(%edi) 454 | .endm 455 | 456 | leal 131072(%esi), %ecx 457 | scrypt_core_gen_loop1: 458 | movl %esi, 64(%esp) 459 | movl %ecx, 68(%esp) 460 | 461 | scrypt_core_macro1a 0, 64 462 | scrypt_core_macro1a 4, 68 463 | scrypt_core_macro1a 8, 72 464 | scrypt_core_macro1a 12, 76 465 | scrypt_core_macro1a 16, 80 466 | scrypt_core_macro1a 20, 84 467 | scrypt_core_macro1a 24, 88 468 | scrypt_core_macro1a 28, 92 469 | scrypt_core_macro1a 32, 96 470 | scrypt_core_macro1a 36, 100 471 | scrypt_core_macro1a 40, 104 472 | scrypt_core_macro1a 44, 108 473 | scrypt_core_macro1a 48, 112 474 | scrypt_core_macro1a 52, 116 475 | scrypt_core_macro1a 56, 120 476 | scrypt_core_macro1a 60, 124 477 | 478 | call salsa8_core_gen 479 | 480 | movl 92(%esp), %edi 481 | scrypt_core_macro2 0, 64 482 | scrypt_core_macro2 4, 68 483 | scrypt_core_macro2 8, 72 484 | scrypt_core_macro2 12, 76 485 | scrypt_core_macro2 16, 80 486 | scrypt_core_macro2 20, 84 487 | scrypt_core_macro2 24, 88 488 | scrypt_core_macro2 28, 92 489 | scrypt_core_macro2 32, 96 490 | scrypt_core_macro2 36, 100 491 | scrypt_core_macro2 40, 104 492 | scrypt_core_macro2 44, 108 493 | scrypt_core_macro2 48, 112 494 | scrypt_core_macro2 52, 116 495 | scrypt_core_macro2 56, 120 496 | scrypt_core_macro2 60, 124 497 | 498 | call salsa8_core_gen 499 | 500 | movl 92(%esp), %edi 501 | scrypt_core_macro3 0, 64 502 | scrypt_core_macro3 4, 68 503 | scrypt_core_macro3 8, 72 504 | scrypt_core_macro3 12, 76 505 | scrypt_core_macro3 16, 80 506 | scrypt_core_macro3 20, 84 507 | scrypt_core_macro3 24, 88 508 | scrypt_core_macro3 28, 92 509 | scrypt_core_macro3 32, 96 510 | scrypt_core_macro3 36, 100 511 | scrypt_core_macro3 40, 104 512 | scrypt_core_macro3 44, 108 513 | scrypt_core_macro3 48, 112 514 | scrypt_core_macro3 52, 116 515 | scrypt_core_macro3 56, 120 516 | scrypt_core_macro3 60, 124 517 | 518 | movl 64(%esp), %esi 519 | movl 68(%esp), %ecx 520 | addl $128, %esi 521 | cmpl %ecx, %esi 522 | jne scrypt_core_gen_loop1 523 | 524 | movl 96(%esp), %esi 525 | movl $1024, %ecx 526 | scrypt_core_gen_loop2: 527 | movl %ecx, 68(%esp) 528 | 529 | movl 64(%edi), %edx 530 | andl $1023, %edx 531 | shll $7, %edx 532 | 533 | scrypt_core_macro1b 0, 64 534 | scrypt_core_macro1b 4, 68 535 | scrypt_core_macro1b 8, 72 536 | scrypt_core_macro1b 12, 76 537 | scrypt_core_macro1b 16, 80 538 | scrypt_core_macro1b 20, 84 539 | scrypt_core_macro1b 24, 88 540 | scrypt_core_macro1b 28, 92 541 | scrypt_core_macro1b 32, 96 542 | scrypt_core_macro1b 36, 100 543 | scrypt_core_macro1b 40, 104 544 | scrypt_core_macro1b 44, 108 545 | scrypt_core_macro1b 48, 112 546 | scrypt_core_macro1b 52, 116 547 | scrypt_core_macro1b 56, 120 548 | scrypt_core_macro1b 60, 124 549 | 550 | call salsa8_core_gen 551 | 552 | movl 92(%esp), %edi 553 | scrypt_core_macro2 0, 64 554 | scrypt_core_macro2 4, 68 555 | scrypt_core_macro2 8, 72 556 | scrypt_core_macro2 12, 76 557 | scrypt_core_macro2 16, 80 558 | scrypt_core_macro2 20, 84 559 | scrypt_core_macro2 24, 88 560 | scrypt_core_macro2 28, 92 561 | scrypt_core_macro2 32, 96 562 | scrypt_core_macro2 36, 100 563 | scrypt_core_macro2 40, 104 564 | scrypt_core_macro2 44, 108 565 | scrypt_core_macro2 48, 112 566 | scrypt_core_macro2 52, 116 567 | scrypt_core_macro2 56, 120 568 | scrypt_core_macro2 60, 124 569 | 570 | call salsa8_core_gen 571 | 572 | movl 92(%esp), %edi 573 | movl 96(%esp), %esi 574 | scrypt_core_macro3 0, 64 575 | scrypt_core_macro3 4, 68 576 | scrypt_core_macro3 8, 72 577 | scrypt_core_macro3 12, 76 578 | scrypt_core_macro3 16, 80 579 | scrypt_core_macro3 20, 84 580 | scrypt_core_macro3 24, 88 581 | scrypt_core_macro3 28, 92 582 | scrypt_core_macro3 32, 96 583 | scrypt_core_macro3 36, 100 584 | scrypt_core_macro3 40, 104 585 | scrypt_core_macro3 44, 108 586 | scrypt_core_macro3 48, 112 587 | scrypt_core_macro3 52, 116 588 | scrypt_core_macro3 56, 120 589 | scrypt_core_macro3 60, 124 590 | 591 | movl 68(%esp), %ecx 592 | subl $1, %ecx 593 | ja scrypt_core_gen_loop2 594 | 595 | addl $72, %esp 596 | popl %esi 597 | popl %edi 598 | popl %ebp 599 | popl %ebx 600 | ret 601 | 602 | 603 | .macro salsa8_core_sse2_doubleround 604 | movdqa %xmm1, %xmm4 605 | paddd %xmm0, %xmm4 606 | movdqa %xmm4, %xmm5 607 | pslld $7, %xmm4 608 | psrld $25, %xmm5 609 | pxor %xmm4, %xmm3 610 | movdqa %xmm0, %xmm4 611 | pxor %xmm5, %xmm3 612 | 613 | paddd %xmm3, %xmm4 614 | movdqa %xmm4, %xmm5 615 | pslld $9, %xmm4 616 | psrld $23, %xmm5 617 | pxor %xmm4, %xmm2 618 | movdqa %xmm3, %xmm4 619 | pxor %xmm5, %xmm2 620 | pshufd $0x93, %xmm3, %xmm3 621 | 622 | paddd %xmm2, %xmm4 623 | movdqa %xmm4, %xmm5 624 | pslld $13, %xmm4 625 | psrld $19, %xmm5 626 | pxor %xmm4, %xmm1 627 | movdqa %xmm2, %xmm4 628 | pxor %xmm5, %xmm1 629 | pshufd $0x4e, %xmm2, %xmm2 630 | 631 | paddd %xmm1, %xmm4 632 | movdqa %xmm4, %xmm5 633 | pslld $18, %xmm4 634 | psrld $14, %xmm5 635 | pxor %xmm4, %xmm0 636 | movdqa %xmm3, %xmm4 637 | pxor %xmm5, %xmm0 638 | pshufd $0x39, %xmm1, %xmm1 639 | 640 | paddd %xmm0, %xmm4 641 | movdqa %xmm4, %xmm5 642 | pslld $7, %xmm4 643 | psrld $25, %xmm5 644 | pxor %xmm4, %xmm1 645 | movdqa %xmm0, %xmm4 646 | pxor %xmm5, %xmm1 647 | 648 | paddd %xmm1, %xmm4 649 | movdqa %xmm4, %xmm5 650 | pslld $9, %xmm4 651 | psrld $23, %xmm5 652 | pxor %xmm4, %xmm2 653 | movdqa %xmm1, %xmm4 654 | pxor %xmm5, %xmm2 655 | pshufd $0x93, %xmm1, %xmm1 656 | 657 | paddd %xmm2, %xmm4 658 | movdqa %xmm4, %xmm5 659 | pslld $13, %xmm4 660 | psrld $19, %xmm5 661 | pxor %xmm4, %xmm3 662 | movdqa %xmm2, %xmm4 663 | pxor %xmm5, %xmm3 664 | pshufd $0x4e, %xmm2, %xmm2 665 | 666 | paddd %xmm3, %xmm4 667 | movdqa %xmm4, %xmm5 668 | pslld $18, %xmm4 669 | psrld $14, %xmm5 670 | pxor %xmm4, %xmm0 671 | pshufd $0x39, %xmm3, %xmm3 672 | pxor %xmm5, %xmm0 673 | .endm 674 | 675 | .macro salsa8_core_sse2 676 | salsa8_core_sse2_doubleround 677 | salsa8_core_sse2_doubleround 678 | salsa8_core_sse2_doubleround 679 | salsa8_core_sse2_doubleround 680 | .endm 681 | 682 | .p2align 5 683 | scrypt_core_sse2: 684 | movl 20(%esp), %edi 685 | movl 24(%esp), %esi 686 | movl %esp, %ebp 687 | subl $128, %esp 688 | andl $-16, %esp 689 | 690 | scrypt_shuffle %edi, 0, %esp, 0 691 | scrypt_shuffle %edi, 64, %esp, 64 692 | 693 | movdqa 96(%esp), %xmm6 694 | movdqa 112(%esp), %xmm7 695 | 696 | movl %esi, %edx 697 | leal 131072(%esi), %ecx 698 | scrypt_core_sse2_loop1: 699 | movdqa 0(%esp), %xmm0 700 | movdqa 16(%esp), %xmm1 701 | movdqa 32(%esp), %xmm2 702 | movdqa 48(%esp), %xmm3 703 | movdqa 64(%esp), %xmm4 704 | movdqa 80(%esp), %xmm5 705 | pxor %xmm4, %xmm0 706 | pxor %xmm5, %xmm1 707 | movdqa %xmm0, 0(%edx) 708 | movdqa %xmm1, 16(%edx) 709 | pxor %xmm6, %xmm2 710 | pxor %xmm7, %xmm3 711 | movdqa %xmm2, 32(%edx) 712 | movdqa %xmm3, 48(%edx) 713 | movdqa %xmm4, 64(%edx) 714 | movdqa %xmm5, 80(%edx) 715 | movdqa %xmm6, 96(%edx) 716 | movdqa %xmm7, 112(%edx) 717 | 718 | salsa8_core_sse2 719 | paddd 0(%edx), %xmm0 720 | paddd 16(%edx), %xmm1 721 | paddd 32(%edx), %xmm2 722 | paddd 48(%edx), %xmm3 723 | movdqa %xmm0, 0(%esp) 724 | movdqa %xmm1, 16(%esp) 725 | movdqa %xmm2, 32(%esp) 726 | movdqa %xmm3, 48(%esp) 727 | 728 | pxor 64(%esp), %xmm0 729 | pxor 80(%esp), %xmm1 730 | pxor %xmm6, %xmm2 731 | pxor %xmm7, %xmm3 732 | movdqa %xmm0, 64(%esp) 733 | movdqa %xmm1, 80(%esp) 734 | movdqa %xmm2, %xmm6 735 | movdqa %xmm3, %xmm7 736 | salsa8_core_sse2 737 | paddd 64(%esp), %xmm0 738 | paddd 80(%esp), %xmm1 739 | paddd %xmm2, %xmm6 740 | paddd %xmm3, %xmm7 741 | movdqa %xmm0, 64(%esp) 742 | movdqa %xmm1, 80(%esp) 743 | 744 | addl $128, %edx 745 | cmpl %ecx, %edx 746 | jne scrypt_core_sse2_loop1 747 | 748 | movdqa 64(%esp), %xmm4 749 | movdqa 80(%esp), %xmm5 750 | 751 | movl $1024, %ecx 752 | scrypt_core_sse2_loop2: 753 | movd %xmm4, %edx 754 | movdqa 0(%esp), %xmm0 755 | movdqa 16(%esp), %xmm1 756 | movdqa 32(%esp), %xmm2 757 | movdqa 48(%esp), %xmm3 758 | andl $1023, %edx 759 | shll $7, %edx 760 | pxor 0(%esi, %edx), %xmm0 761 | pxor 16(%esi, %edx), %xmm1 762 | pxor 32(%esi, %edx), %xmm2 763 | pxor 48(%esi, %edx), %xmm3 764 | 765 | pxor %xmm4, %xmm0 766 | pxor %xmm5, %xmm1 767 | movdqa %xmm0, 0(%esp) 768 | movdqa %xmm1, 16(%esp) 769 | pxor %xmm6, %xmm2 770 | pxor %xmm7, %xmm3 771 | movdqa %xmm2, 32(%esp) 772 | movdqa %xmm3, 48(%esp) 773 | salsa8_core_sse2 774 | paddd 0(%esp), %xmm0 775 | paddd 16(%esp), %xmm1 776 | paddd 32(%esp), %xmm2 777 | paddd 48(%esp), %xmm3 778 | movdqa %xmm0, 0(%esp) 779 | movdqa %xmm1, 16(%esp) 780 | movdqa %xmm2, 32(%esp) 781 | movdqa %xmm3, 48(%esp) 782 | 783 | pxor 64(%esi, %edx), %xmm0 784 | pxor 80(%esi, %edx), %xmm1 785 | pxor 96(%esi, %edx), %xmm2 786 | pxor 112(%esi, %edx), %xmm3 787 | pxor 64(%esp), %xmm0 788 | pxor 80(%esp), %xmm1 789 | pxor %xmm6, %xmm2 790 | pxor %xmm7, %xmm3 791 | movdqa %xmm0, 64(%esp) 792 | movdqa %xmm1, 80(%esp) 793 | movdqa %xmm2, %xmm6 794 | movdqa %xmm3, %xmm7 795 | salsa8_core_sse2 796 | paddd 64(%esp), %xmm0 797 | paddd 80(%esp), %xmm1 798 | paddd %xmm2, %xmm6 799 | paddd %xmm3, %xmm7 800 | movdqa %xmm0, %xmm4 801 | movdqa %xmm1, %xmm5 802 | movdqa %xmm0, 64(%esp) 803 | movdqa %xmm1, 80(%esp) 804 | 805 | subl $1, %ecx 806 | ja scrypt_core_sse2_loop2 807 | 808 | movdqa %xmm6, 96(%esp) 809 | movdqa %xmm7, 112(%esp) 810 | 811 | scrypt_shuffle %esp, 0, %edi, 0 812 | scrypt_shuffle %esp, 64, %edi, 64 813 | 814 | movl %ebp, %esp 815 | popl %esi 816 | popl %edi 817 | popl %ebp 818 | popl %ebx 819 | ret 820 | 821 | #endif 822 | -------------------------------------------------------------------------------- /compat/jansson/value.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include "hashtable.h" 17 | #include "jansson_private.h" 18 | #include "utf.h" 19 | #include "util.h" 20 | 21 | 22 | static inline void json_init(json_t *json, json_type type) 23 | { 24 | json->type = type; 25 | json->refcount = 1; 26 | } 27 | 28 | 29 | /*** object ***/ 30 | 31 | /* This macro just returns a pointer that's a few bytes backwards from 32 | string. This makes it possible to pass a pointer to object_key_t 33 | when only the string inside it is used, without actually creating 34 | an object_key_t instance. */ 35 | #define string_to_key(string) container_of(string, object_key_t, key) 36 | 37 | static unsigned int hash_key(const void *ptr) 38 | { 39 | const char *str = ((const object_key_t *)ptr)->key; 40 | 41 | unsigned int hash = 5381; 42 | unsigned int c; 43 | 44 | while((c = (unsigned int)*str)) 45 | { 46 | hash = ((hash << 5) + hash) + c; 47 | str++; 48 | } 49 | 50 | return hash; 51 | } 52 | 53 | static int key_equal(const void *ptr1, const void *ptr2) 54 | { 55 | return strcmp(((const object_key_t *)ptr1)->key, 56 | ((const object_key_t *)ptr2)->key) == 0; 57 | } 58 | 59 | static void value_decref(void *value) 60 | { 61 | json_decref((json_t *)value); 62 | } 63 | 64 | json_t *json_object(void) 65 | { 66 | json_object_t *object = malloc(sizeof(json_object_t)); 67 | if(!object) 68 | return NULL; 69 | json_init(&object->json, JSON_OBJECT); 70 | 71 | if(hashtable_init(&object->hashtable, hash_key, key_equal, 72 | free, value_decref)) 73 | { 74 | free(object); 75 | return NULL; 76 | } 77 | 78 | object->serial = 0; 79 | object->visited = 0; 80 | 81 | return &object->json; 82 | } 83 | 84 | static void json_delete_object(json_object_t *object) 85 | { 86 | hashtable_close(&object->hashtable); 87 | free(object); 88 | } 89 | 90 | unsigned int json_object_size(const json_t *json) 91 | { 92 | json_object_t *object; 93 | 94 | if(!json_is_object(json)) 95 | return -1; 96 | 97 | object = json_to_object(json); 98 | return object->hashtable.size; 99 | } 100 | 101 | json_t *json_object_get(const json_t *json, const char *key) 102 | { 103 | json_object_t *object; 104 | 105 | if(!json_is_object(json)) 106 | return NULL; 107 | 108 | object = json_to_object(json); 109 | return hashtable_get(&object->hashtable, string_to_key(key)); 110 | } 111 | 112 | int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) 113 | { 114 | json_object_t *object; 115 | object_key_t *k; 116 | 117 | if(!key || !value) 118 | return -1; 119 | 120 | if(!json_is_object(json) || json == value) 121 | { 122 | json_decref(value); 123 | return -1; 124 | } 125 | object = json_to_object(json); 126 | 127 | k = malloc(sizeof(object_key_t) + strlen(key) + 1); 128 | if(!k) 129 | return -1; 130 | 131 | k->serial = object->serial++; 132 | strcpy(k->key, key); 133 | 134 | if(hashtable_set(&object->hashtable, k, value)) 135 | { 136 | json_decref(value); 137 | return -1; 138 | } 139 | 140 | return 0; 141 | } 142 | 143 | int json_object_set_new(json_t *json, const char *key, json_t *value) 144 | { 145 | if(!key || !utf8_check_string(key, -1)) 146 | { 147 | json_decref(value); 148 | return -1; 149 | } 150 | 151 | return json_object_set_new_nocheck(json, key, value); 152 | } 153 | 154 | int json_object_del(json_t *json, const char *key) 155 | { 156 | json_object_t *object; 157 | 158 | if(!json_is_object(json)) 159 | return -1; 160 | 161 | object = json_to_object(json); 162 | return hashtable_del(&object->hashtable, string_to_key(key)); 163 | } 164 | 165 | int json_object_clear(json_t *json) 166 | { 167 | json_object_t *object; 168 | 169 | if(!json_is_object(json)) 170 | return -1; 171 | 172 | object = json_to_object(json); 173 | hashtable_clear(&object->hashtable); 174 | 175 | return 0; 176 | } 177 | 178 | int json_object_update(json_t *object, json_t *other) 179 | { 180 | void *iter; 181 | 182 | if(!json_is_object(object) || !json_is_object(other)) 183 | return -1; 184 | 185 | iter = json_object_iter(other); 186 | while(iter) { 187 | const char *key; 188 | json_t *value; 189 | 190 | key = json_object_iter_key(iter); 191 | value = json_object_iter_value(iter); 192 | 193 | if(json_object_set_nocheck(object, key, value)) 194 | return -1; 195 | 196 | iter = json_object_iter_next(other, iter); 197 | } 198 | 199 | return 0; 200 | } 201 | 202 | void *json_object_iter(json_t *json) 203 | { 204 | json_object_t *object; 205 | 206 | if(!json_is_object(json)) 207 | return NULL; 208 | 209 | object = json_to_object(json); 210 | return hashtable_iter(&object->hashtable); 211 | } 212 | 213 | void *json_object_iter_at(json_t *json, const char *key) 214 | { 215 | json_object_t *object; 216 | 217 | if(!key || !json_is_object(json)) 218 | return NULL; 219 | 220 | object = json_to_object(json); 221 | return hashtable_iter_at(&object->hashtable, string_to_key(key)); 222 | } 223 | 224 | void *json_object_iter_next(json_t *json, void *iter) 225 | { 226 | json_object_t *object; 227 | 228 | if(!json_is_object(json) || iter == NULL) 229 | return NULL; 230 | 231 | object = json_to_object(json); 232 | return hashtable_iter_next(&object->hashtable, iter); 233 | } 234 | 235 | const object_key_t *jsonp_object_iter_fullkey(void *iter) 236 | { 237 | if(!iter) 238 | return NULL; 239 | 240 | return hashtable_iter_key(iter); 241 | } 242 | 243 | const char *json_object_iter_key(void *iter) 244 | { 245 | if(!iter) 246 | return NULL; 247 | 248 | return jsonp_object_iter_fullkey(iter)->key; 249 | } 250 | 251 | json_t *json_object_iter_value(void *iter) 252 | { 253 | if(!iter) 254 | return NULL; 255 | 256 | return (json_t *)hashtable_iter_value(iter); 257 | } 258 | 259 | int json_object_iter_set_new(json_t *json, void *iter, json_t *value) 260 | { 261 | json_object_t *object; 262 | 263 | if(!json_is_object(json) || !iter || !value) 264 | return -1; 265 | 266 | object = json_to_object(json); 267 | hashtable_iter_set(&object->hashtable, iter, value); 268 | 269 | return 0; 270 | } 271 | 272 | static int json_object_equal(json_t *object1, json_t *object2) 273 | { 274 | void *iter; 275 | 276 | if(json_object_size(object1) != json_object_size(object2)) 277 | return 0; 278 | 279 | iter = json_object_iter(object1); 280 | while(iter) 281 | { 282 | const char *key; 283 | json_t *value1, *value2; 284 | 285 | key = json_object_iter_key(iter); 286 | value1 = json_object_iter_value(iter); 287 | value2 = json_object_get(object2, key); 288 | 289 | if(!json_equal(value1, value2)) 290 | return 0; 291 | 292 | iter = json_object_iter_next(object1, iter); 293 | } 294 | 295 | return 1; 296 | } 297 | 298 | static json_t *json_object_copy(json_t *object) 299 | { 300 | json_t *result; 301 | void *iter; 302 | 303 | result = json_object(); 304 | if(!result) 305 | return NULL; 306 | 307 | iter = json_object_iter(object); 308 | while(iter) 309 | { 310 | const char *key; 311 | json_t *value; 312 | 313 | key = json_object_iter_key(iter); 314 | value = json_object_iter_value(iter); 315 | json_object_set_nocheck(result, key, value); 316 | 317 | iter = json_object_iter_next(object, iter); 318 | } 319 | 320 | return result; 321 | } 322 | 323 | static json_t *json_object_deep_copy(json_t *object) 324 | { 325 | json_t *result; 326 | void *iter; 327 | 328 | result = json_object(); 329 | if(!result) 330 | return NULL; 331 | 332 | iter = json_object_iter(object); 333 | while(iter) 334 | { 335 | const char *key; 336 | json_t *value; 337 | 338 | key = json_object_iter_key(iter); 339 | value = json_object_iter_value(iter); 340 | json_object_set_new_nocheck(result, key, json_deep_copy(value)); 341 | 342 | iter = json_object_iter_next(object, iter); 343 | } 344 | 345 | return result; 346 | } 347 | 348 | 349 | /*** array ***/ 350 | 351 | json_t *json_array(void) 352 | { 353 | json_array_t *array = malloc(sizeof(json_array_t)); 354 | if(!array) 355 | return NULL; 356 | json_init(&array->json, JSON_ARRAY); 357 | 358 | array->entries = 0; 359 | array->size = 8; 360 | 361 | array->table = malloc(array->size * sizeof(json_t *)); 362 | if(!array->table) { 363 | free(array); 364 | return NULL; 365 | } 366 | 367 | array->visited = 0; 368 | 369 | return &array->json; 370 | } 371 | 372 | static void json_delete_array(json_array_t *array) 373 | { 374 | unsigned int i; 375 | 376 | for(i = 0; i < array->entries; i++) 377 | json_decref(array->table[i]); 378 | 379 | free(array->table); 380 | free(array); 381 | } 382 | 383 | unsigned int json_array_size(const json_t *json) 384 | { 385 | if(!json_is_array(json)) 386 | return 0; 387 | 388 | return json_to_array(json)->entries; 389 | } 390 | 391 | json_t *json_array_get(const json_t *json, unsigned int index) 392 | { 393 | json_array_t *array; 394 | if(!json_is_array(json)) 395 | return NULL; 396 | array = json_to_array(json); 397 | 398 | if(index >= array->entries) 399 | return NULL; 400 | 401 | return array->table[index]; 402 | } 403 | 404 | int json_array_set_new(json_t *json, unsigned int index, json_t *value) 405 | { 406 | json_array_t *array; 407 | 408 | if(!value) 409 | return -1; 410 | 411 | if(!json_is_array(json) || json == value) 412 | { 413 | json_decref(value); 414 | return -1; 415 | } 416 | array = json_to_array(json); 417 | 418 | if(index >= array->entries) 419 | { 420 | json_decref(value); 421 | return -1; 422 | } 423 | 424 | json_decref(array->table[index]); 425 | array->table[index] = value; 426 | 427 | return 0; 428 | } 429 | 430 | static void array_move(json_array_t *array, unsigned int dest, 431 | unsigned int src, unsigned int count) 432 | { 433 | memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *)); 434 | } 435 | 436 | static void array_copy(json_t **dest, unsigned int dpos, 437 | json_t **src, unsigned int spos, 438 | unsigned int count) 439 | { 440 | memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); 441 | } 442 | 443 | static json_t **json_array_grow(json_array_t *array, 444 | unsigned int amount, 445 | int copy) 446 | { 447 | unsigned int new_size; 448 | json_t **old_table, **new_table; 449 | 450 | if(array->entries + amount <= array->size) 451 | return array->table; 452 | 453 | old_table = array->table; 454 | 455 | new_size = max(array->size + amount, array->size * 2); 456 | new_table = malloc(new_size * sizeof(json_t *)); 457 | if(!new_table) 458 | return NULL; 459 | 460 | array->size = new_size; 461 | array->table = new_table; 462 | 463 | if(copy) { 464 | array_copy(array->table, 0, old_table, 0, array->entries); 465 | free(old_table); 466 | return array->table; 467 | } 468 | 469 | return old_table; 470 | } 471 | 472 | int json_array_append_new(json_t *json, json_t *value) 473 | { 474 | json_array_t *array; 475 | 476 | if(!value) 477 | return -1; 478 | 479 | if(!json_is_array(json) || json == value) 480 | { 481 | json_decref(value); 482 | return -1; 483 | } 484 | array = json_to_array(json); 485 | 486 | if(!json_array_grow(array, 1, 1)) { 487 | json_decref(value); 488 | return -1; 489 | } 490 | 491 | array->table[array->entries] = value; 492 | array->entries++; 493 | 494 | return 0; 495 | } 496 | 497 | int json_array_insert_new(json_t *json, unsigned int index, json_t *value) 498 | { 499 | json_array_t *array; 500 | json_t **old_table; 501 | 502 | if(!value) 503 | return -1; 504 | 505 | if(!json_is_array(json) || json == value) { 506 | json_decref(value); 507 | return -1; 508 | } 509 | array = json_to_array(json); 510 | 511 | if(index > array->entries) { 512 | json_decref(value); 513 | return -1; 514 | } 515 | 516 | old_table = json_array_grow(array, 1, 0); 517 | if(!old_table) { 518 | json_decref(value); 519 | return -1; 520 | } 521 | 522 | if(old_table != array->table) { 523 | array_copy(array->table, 0, old_table, 0, index); 524 | array_copy(array->table, index + 1, old_table, index, 525 | array->entries - index); 526 | free(old_table); 527 | } 528 | else 529 | array_move(array, index + 1, index, array->entries - index); 530 | 531 | array->table[index] = value; 532 | array->entries++; 533 | 534 | return 0; 535 | } 536 | 537 | int json_array_remove(json_t *json, unsigned int index) 538 | { 539 | json_array_t *array; 540 | 541 | if(!json_is_array(json)) 542 | return -1; 543 | array = json_to_array(json); 544 | 545 | if(index >= array->entries) 546 | return -1; 547 | 548 | json_decref(array->table[index]); 549 | 550 | array_move(array, index, index + 1, array->entries - index); 551 | array->entries--; 552 | 553 | return 0; 554 | } 555 | 556 | int json_array_clear(json_t *json) 557 | { 558 | json_array_t *array; 559 | unsigned int i; 560 | 561 | if(!json_is_array(json)) 562 | return -1; 563 | array = json_to_array(json); 564 | 565 | for(i = 0; i < array->entries; i++) 566 | json_decref(array->table[i]); 567 | 568 | array->entries = 0; 569 | return 0; 570 | } 571 | 572 | int json_array_extend(json_t *json, json_t *other_json) 573 | { 574 | json_array_t *array, *other; 575 | unsigned int i; 576 | 577 | if(!json_is_array(json) || !json_is_array(other_json)) 578 | return -1; 579 | array = json_to_array(json); 580 | other = json_to_array(other_json); 581 | 582 | if(!json_array_grow(array, other->entries, 1)) 583 | return -1; 584 | 585 | for(i = 0; i < other->entries; i++) 586 | json_incref(other->table[i]); 587 | 588 | array_copy(array->table, array->entries, other->table, 0, other->entries); 589 | 590 | array->entries += other->entries; 591 | return 0; 592 | } 593 | 594 | static int json_array_equal(json_t *array1, json_t *array2) 595 | { 596 | unsigned int i, size; 597 | 598 | size = json_array_size(array1); 599 | if(size != json_array_size(array2)) 600 | return 0; 601 | 602 | for(i = 0; i < size; i++) 603 | { 604 | json_t *value1, *value2; 605 | 606 | value1 = json_array_get(array1, i); 607 | value2 = json_array_get(array2, i); 608 | 609 | if(!json_equal(value1, value2)) 610 | return 0; 611 | } 612 | 613 | return 1; 614 | } 615 | 616 | static json_t *json_array_copy(json_t *array) 617 | { 618 | json_t *result; 619 | unsigned int i; 620 | 621 | result = json_array(); 622 | if(!result) 623 | return NULL; 624 | 625 | for(i = 0; i < json_array_size(array); i++) 626 | json_array_append(result, json_array_get(array, i)); 627 | 628 | return result; 629 | } 630 | 631 | static json_t *json_array_deep_copy(json_t *array) 632 | { 633 | json_t *result; 634 | unsigned int i; 635 | 636 | result = json_array(); 637 | if(!result) 638 | return NULL; 639 | 640 | for(i = 0; i < json_array_size(array); i++) 641 | json_array_append_new(result, json_deep_copy(json_array_get(array, i))); 642 | 643 | return result; 644 | } 645 | 646 | /*** string ***/ 647 | 648 | json_t *json_string_nocheck(const char *value) 649 | { 650 | json_string_t *string; 651 | 652 | if(!value) 653 | return NULL; 654 | 655 | string = malloc(sizeof(json_string_t)); 656 | if(!string) 657 | return NULL; 658 | json_init(&string->json, JSON_STRING); 659 | 660 | string->value = strdup(value); 661 | if(!string->value) { 662 | free(string); 663 | return NULL; 664 | } 665 | 666 | return &string->json; 667 | } 668 | 669 | json_t *json_string(const char *value) 670 | { 671 | if(!value || !utf8_check_string(value, -1)) 672 | return NULL; 673 | 674 | return json_string_nocheck(value); 675 | } 676 | 677 | const char *json_string_value(const json_t *json) 678 | { 679 | if(!json_is_string(json)) 680 | return NULL; 681 | 682 | return json_to_string(json)->value; 683 | } 684 | 685 | int json_string_set_nocheck(json_t *json, const char *value) 686 | { 687 | char *dup; 688 | json_string_t *string; 689 | 690 | dup = strdup(value); 691 | if(!dup) 692 | return -1; 693 | 694 | string = json_to_string(json); 695 | free(string->value); 696 | string->value = dup; 697 | 698 | return 0; 699 | } 700 | 701 | int json_string_set(json_t *json, const char *value) 702 | { 703 | if(!value || !utf8_check_string(value, -1)) 704 | return -1; 705 | 706 | return json_string_set_nocheck(json, value); 707 | } 708 | 709 | static void json_delete_string(json_string_t *string) 710 | { 711 | free(string->value); 712 | free(string); 713 | } 714 | 715 | static int json_string_equal(json_t *string1, json_t *string2) 716 | { 717 | return strcmp(json_string_value(string1), json_string_value(string2)) == 0; 718 | } 719 | 720 | static json_t *json_string_copy(json_t *string) 721 | { 722 | return json_string_nocheck(json_string_value(string)); 723 | } 724 | 725 | 726 | /*** integer ***/ 727 | 728 | json_t *json_integer(int value) 729 | { 730 | json_integer_t *integer = malloc(sizeof(json_integer_t)); 731 | if(!integer) 732 | return NULL; 733 | json_init(&integer->json, JSON_INTEGER); 734 | 735 | integer->value = value; 736 | return &integer->json; 737 | } 738 | 739 | int json_integer_value(const json_t *json) 740 | { 741 | if(!json_is_integer(json)) 742 | return 0; 743 | 744 | return json_to_integer(json)->value; 745 | } 746 | 747 | int json_integer_set(json_t *json, int value) 748 | { 749 | if(!json_is_integer(json)) 750 | return -1; 751 | 752 | json_to_integer(json)->value = value; 753 | 754 | return 0; 755 | } 756 | 757 | static void json_delete_integer(json_integer_t *integer) 758 | { 759 | free(integer); 760 | } 761 | 762 | static int json_integer_equal(json_t *integer1, json_t *integer2) 763 | { 764 | return json_integer_value(integer1) == json_integer_value(integer2); 765 | } 766 | 767 | static json_t *json_integer_copy(json_t *integer) 768 | { 769 | return json_integer(json_integer_value(integer)); 770 | } 771 | 772 | 773 | /*** real ***/ 774 | 775 | json_t *json_real(double value) 776 | { 777 | json_real_t *real = malloc(sizeof(json_real_t)); 778 | if(!real) 779 | return NULL; 780 | json_init(&real->json, JSON_REAL); 781 | 782 | real->value = value; 783 | return &real->json; 784 | } 785 | 786 | double json_real_value(const json_t *json) 787 | { 788 | if(!json_is_real(json)) 789 | return 0; 790 | 791 | return json_to_real(json)->value; 792 | } 793 | 794 | int json_real_set(json_t *json, double value) 795 | { 796 | if(!json_is_real(json)) 797 | return 0; 798 | 799 | json_to_real(json)->value = value; 800 | 801 | return 0; 802 | } 803 | 804 | static void json_delete_real(json_real_t *real) 805 | { 806 | free(real); 807 | } 808 | 809 | static int json_real_equal(json_t *real1, json_t *real2) 810 | { 811 | return json_real_value(real1) == json_real_value(real2); 812 | } 813 | 814 | static json_t *json_real_copy(json_t *real) 815 | { 816 | return json_real(json_real_value(real)); 817 | } 818 | 819 | 820 | /*** number ***/ 821 | 822 | double json_number_value(const json_t *json) 823 | { 824 | if(json_is_integer(json)) 825 | return json_integer_value(json); 826 | else if(json_is_real(json)) 827 | return json_real_value(json); 828 | else 829 | return 0.0; 830 | } 831 | 832 | 833 | /*** simple values ***/ 834 | 835 | json_t *json_true(void) 836 | { 837 | static json_t the_true = { 838 | .type = JSON_TRUE, 839 | .refcount = (unsigned int)-1 840 | }; 841 | return &the_true; 842 | } 843 | 844 | 845 | json_t *json_false(void) 846 | { 847 | static json_t the_false = { 848 | .type = JSON_FALSE, 849 | .refcount = (unsigned int)-1 850 | }; 851 | return &the_false; 852 | } 853 | 854 | 855 | json_t *json_null(void) 856 | { 857 | static json_t the_null = { 858 | .type = JSON_NULL, 859 | .refcount = (unsigned int)-1 860 | }; 861 | return &the_null; 862 | } 863 | 864 | 865 | /*** deletion ***/ 866 | 867 | void json_delete(json_t *json) 868 | { 869 | if(json_is_object(json)) 870 | json_delete_object(json_to_object(json)); 871 | 872 | else if(json_is_array(json)) 873 | json_delete_array(json_to_array(json)); 874 | 875 | else if(json_is_string(json)) 876 | json_delete_string(json_to_string(json)); 877 | 878 | else if(json_is_integer(json)) 879 | json_delete_integer(json_to_integer(json)); 880 | 881 | else if(json_is_real(json)) 882 | json_delete_real(json_to_real(json)); 883 | 884 | /* json_delete is not called for true, false or null */ 885 | } 886 | 887 | 888 | /*** equality ***/ 889 | 890 | int json_equal(json_t *json1, json_t *json2) 891 | { 892 | if(!json1 || !json2) 893 | return 0; 894 | 895 | if(json_typeof(json1) != json_typeof(json2)) 896 | return 0; 897 | 898 | /* this covers true, false and null as they are singletons */ 899 | if(json1 == json2) 900 | return 1; 901 | 902 | if(json_is_object(json1)) 903 | return json_object_equal(json1, json2); 904 | 905 | if(json_is_array(json1)) 906 | return json_array_equal(json1, json2); 907 | 908 | if(json_is_string(json1)) 909 | return json_string_equal(json1, json2); 910 | 911 | if(json_is_integer(json1)) 912 | return json_integer_equal(json1, json2); 913 | 914 | if(json_is_real(json1)) 915 | return json_real_equal(json1, json2); 916 | 917 | return 0; 918 | } 919 | 920 | 921 | /*** copying ***/ 922 | 923 | json_t *json_copy(json_t *json) 924 | { 925 | if(!json) 926 | return NULL; 927 | 928 | if(json_is_object(json)) 929 | return json_object_copy(json); 930 | 931 | if(json_is_array(json)) 932 | return json_array_copy(json); 933 | 934 | if(json_is_string(json)) 935 | return json_string_copy(json); 936 | 937 | if(json_is_integer(json)) 938 | return json_integer_copy(json); 939 | 940 | if(json_is_real(json)) 941 | return json_real_copy(json); 942 | 943 | if(json_is_true(json) || json_is_false(json) || json_is_null(json)) 944 | return json; 945 | 946 | return NULL; 947 | } 948 | 949 | json_t *json_deep_copy(json_t *json) 950 | { 951 | if(!json) 952 | return NULL; 953 | 954 | if(json_is_object(json)) 955 | return json_object_deep_copy(json); 956 | 957 | if(json_is_array(json)) 958 | return json_array_deep_copy(json); 959 | 960 | /* for the rest of the types, deep copying doesn't differ from 961 | shallow copying */ 962 | 963 | if(json_is_string(json)) 964 | return json_string_copy(json); 965 | 966 | if(json_is_integer(json)) 967 | return json_integer_copy(json); 968 | 969 | if(json_is_real(json)) 970 | return json_real_copy(json); 971 | 972 | if(json_is_true(json) || json_is_false(json) || json_is_null(json)) 973 | return json; 974 | 975 | return NULL; 976 | } 977 | -------------------------------------------------------------------------------- /compat/jansson/load.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2010 Petri Lehtinen 3 | * 4 | * Jansson is free software; you can redistribute it and/or modify 5 | * it under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include "jansson_private.h" 20 | #include "strbuffer.h" 21 | #include "utf.h" 22 | 23 | #define TOKEN_INVALID -1 24 | #define TOKEN_EOF 0 25 | #define TOKEN_STRING 256 26 | #define TOKEN_INTEGER 257 27 | #define TOKEN_REAL 258 28 | #define TOKEN_TRUE 259 29 | #define TOKEN_FALSE 260 30 | #define TOKEN_NULL 261 31 | 32 | /* read one byte from stream, return EOF on end of file */ 33 | typedef int (*get_func)(void *data); 34 | 35 | /* return non-zero if end of file has been reached */ 36 | typedef int (*eof_func)(void *data); 37 | 38 | typedef struct { 39 | get_func get; 40 | eof_func eof; 41 | void *data; 42 | int stream_pos; 43 | char buffer[5]; 44 | int buffer_pos; 45 | } stream_t; 46 | 47 | 48 | typedef struct { 49 | stream_t stream; 50 | strbuffer_t saved_text; 51 | int token; 52 | int line, column; 53 | union { 54 | char *string; 55 | int integer; 56 | double real; 57 | } value; 58 | } lex_t; 59 | 60 | 61 | /*** error reporting ***/ 62 | 63 | static void error_init(json_error_t *error) 64 | { 65 | if(error) 66 | { 67 | error->text[0] = '\0'; 68 | error->line = -1; 69 | } 70 | } 71 | 72 | static void error_set(json_error_t *error, const lex_t *lex, 73 | const char *msg, ...) 74 | { 75 | va_list ap; 76 | char text[JSON_ERROR_TEXT_LENGTH]; 77 | 78 | if(!error || error->text[0] != '\0') { 79 | /* error already set */ 80 | return; 81 | } 82 | 83 | va_start(ap, msg); 84 | vsnprintf(text, JSON_ERROR_TEXT_LENGTH, msg, ap); 85 | va_end(ap); 86 | 87 | if(lex) 88 | { 89 | const char *saved_text = strbuffer_value(&lex->saved_text); 90 | error->line = lex->line; 91 | if(saved_text && saved_text[0]) 92 | { 93 | if(lex->saved_text.length <= 20) { 94 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, 95 | "%s near '%s'", text, saved_text); 96 | } 97 | else 98 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); 99 | } 100 | else 101 | { 102 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, 103 | "%s near end of file", text); 104 | } 105 | } 106 | else 107 | { 108 | error->line = -1; 109 | snprintf(error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); 110 | } 111 | } 112 | 113 | 114 | /*** lexical analyzer ***/ 115 | 116 | static void 117 | stream_init(stream_t *stream, get_func get, eof_func eof, void *data) 118 | { 119 | stream->get = get; 120 | stream->eof = eof; 121 | stream->data = data; 122 | stream->stream_pos = 0; 123 | stream->buffer[0] = '\0'; 124 | stream->buffer_pos = 0; 125 | } 126 | 127 | static char stream_get(stream_t *stream, json_error_t *error) 128 | { 129 | char c; 130 | 131 | if(!stream->buffer[stream->buffer_pos]) 132 | { 133 | stream->buffer[0] = stream->get(stream->data); 134 | stream->buffer_pos = 0; 135 | 136 | c = stream->buffer[0]; 137 | 138 | if((unsigned char)c >= 0x80 && c != (char)EOF) 139 | { 140 | /* multi-byte UTF-8 sequence */ 141 | int i, count; 142 | 143 | count = utf8_check_first(c); 144 | if(!count) 145 | goto out; 146 | 147 | assert(count >= 2); 148 | 149 | for(i = 1; i < count; i++) 150 | stream->buffer[i] = stream->get(stream->data); 151 | 152 | if(!utf8_check_full(stream->buffer, count, NULL)) 153 | goto out; 154 | 155 | stream->stream_pos += count; 156 | stream->buffer[count] = '\0'; 157 | } 158 | else { 159 | stream->buffer[1] = '\0'; 160 | stream->stream_pos++; 161 | } 162 | } 163 | 164 | return stream->buffer[stream->buffer_pos++]; 165 | 166 | out: 167 | error_set(error, NULL, "unable to decode byte 0x%x at position %d", 168 | (unsigned char)c, stream->stream_pos); 169 | 170 | stream->buffer[0] = EOF; 171 | stream->buffer[1] = '\0'; 172 | stream->buffer_pos = 1; 173 | 174 | return EOF; 175 | } 176 | 177 | static void stream_unget(stream_t *stream, char c) 178 | { 179 | assert(stream->buffer_pos > 0); 180 | stream->buffer_pos--; 181 | assert(stream->buffer[stream->buffer_pos] == c); 182 | } 183 | 184 | 185 | static int lex_get(lex_t *lex, json_error_t *error) 186 | { 187 | return stream_get(&lex->stream, error); 188 | } 189 | 190 | static int lex_eof(lex_t *lex) 191 | { 192 | return lex->stream.eof(lex->stream.data); 193 | } 194 | 195 | static void lex_save(lex_t *lex, char c) 196 | { 197 | strbuffer_append_byte(&lex->saved_text, c); 198 | } 199 | 200 | static int lex_get_save(lex_t *lex, json_error_t *error) 201 | { 202 | char c = stream_get(&lex->stream, error); 203 | lex_save(lex, c); 204 | return c; 205 | } 206 | 207 | static void lex_unget_unsave(lex_t *lex, char c) 208 | { 209 | char d; 210 | stream_unget(&lex->stream, c); 211 | d = strbuffer_pop(&lex->saved_text); 212 | assert(c == d); 213 | } 214 | 215 | static void lex_save_cached(lex_t *lex) 216 | { 217 | while(lex->stream.buffer[lex->stream.buffer_pos] != '\0') 218 | { 219 | lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); 220 | lex->stream.buffer_pos++; 221 | } 222 | } 223 | 224 | /* assumes that str points to 'u' plus at least 4 valid hex digits */ 225 | static int32_t decode_unicode_escape(const char *str) 226 | { 227 | int i; 228 | int32_t value = 0; 229 | 230 | assert(str[0] == 'u'); 231 | 232 | for(i = 1; i <= 4; i++) { 233 | char c = str[i]; 234 | value <<= 4; 235 | if(isdigit(c)) 236 | value += c - '0'; 237 | else if(islower(c)) 238 | value += c - 'a' + 10; 239 | else if(isupper(c)) 240 | value += c - 'A' + 10; 241 | else 242 | assert(0); 243 | } 244 | 245 | return value; 246 | } 247 | 248 | static void lex_scan_string(lex_t *lex, json_error_t *error) 249 | { 250 | char c; 251 | const char *p; 252 | char *t; 253 | int i; 254 | 255 | lex->value.string = NULL; 256 | lex->token = TOKEN_INVALID; 257 | 258 | c = lex_get_save(lex, error); 259 | 260 | while(c != '"') { 261 | if(c == (char)EOF) { 262 | lex_unget_unsave(lex, c); 263 | if(lex_eof(lex)) 264 | error_set(error, lex, "premature end of input"); 265 | goto out; 266 | } 267 | 268 | else if((unsigned char)c <= 0x1F) { 269 | /* control character */ 270 | lex_unget_unsave(lex, c); 271 | if(c == '\n') 272 | error_set(error, lex, "unexpected newline", c); 273 | else 274 | error_set(error, lex, "control character 0x%x", c); 275 | goto out; 276 | } 277 | 278 | else if(c == '\\') { 279 | c = lex_get_save(lex, error); 280 | if(c == 'u') { 281 | c = lex_get_save(lex, error); 282 | for(i = 0; i < 4; i++) { 283 | if(!isxdigit(c)) { 284 | lex_unget_unsave(lex, c); 285 | error_set(error, lex, "invalid escape"); 286 | goto out; 287 | } 288 | c = lex_get_save(lex, error); 289 | } 290 | } 291 | else if(c == '"' || c == '\\' || c == '/' || c == 'b' || 292 | c == 'f' || c == 'n' || c == 'r' || c == 't') 293 | c = lex_get_save(lex, error); 294 | else { 295 | lex_unget_unsave(lex, c); 296 | error_set(error, lex, "invalid escape"); 297 | goto out; 298 | } 299 | } 300 | else 301 | c = lex_get_save(lex, error); 302 | } 303 | 304 | /* the actual value is at most of the same length as the source 305 | string, because: 306 | - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte 307 | - a single \uXXXX escape (length 6) is converted to at most 3 bytes 308 | - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair 309 | are converted to 4 bytes 310 | */ 311 | lex->value.string = malloc(lex->saved_text.length + 1); 312 | if(!lex->value.string) { 313 | /* this is not very nice, since TOKEN_INVALID is returned */ 314 | goto out; 315 | } 316 | 317 | /* the target */ 318 | t = lex->value.string; 319 | 320 | /* + 1 to skip the " */ 321 | p = strbuffer_value(&lex->saved_text) + 1; 322 | 323 | while(*p != '"') { 324 | if(*p == '\\') { 325 | p++; 326 | if(*p == 'u') { 327 | char buffer[4]; 328 | int length; 329 | int32_t value; 330 | 331 | value = decode_unicode_escape(p); 332 | p += 5; 333 | 334 | if(0xD800 <= value && value <= 0xDBFF) { 335 | /* surrogate pair */ 336 | if(*p == '\\' && *(p + 1) == 'u') { 337 | int32_t value2 = decode_unicode_escape(++p); 338 | p += 5; 339 | 340 | if(0xDC00 <= value2 && value2 <= 0xDFFF) { 341 | /* valid second surrogate */ 342 | value = 343 | ((value - 0xD800) << 10) + 344 | (value2 - 0xDC00) + 345 | 0x10000; 346 | } 347 | else { 348 | /* invalid second surrogate */ 349 | error_set(error, lex, 350 | "invalid Unicode '\\u%04X\\u%04X'", 351 | value, value2); 352 | goto out; 353 | } 354 | } 355 | else { 356 | /* no second surrogate */ 357 | error_set(error, lex, "invalid Unicode '\\u%04X'", 358 | value); 359 | goto out; 360 | } 361 | } 362 | else if(0xDC00 <= value && value <= 0xDFFF) { 363 | error_set(error, lex, "invalid Unicode '\\u%04X'", value); 364 | goto out; 365 | } 366 | else if(value == 0) 367 | { 368 | error_set(error, lex, "\\u0000 is not allowed"); 369 | goto out; 370 | } 371 | 372 | if(utf8_encode(value, buffer, &length)) 373 | assert(0); 374 | 375 | memcpy(t, buffer, length); 376 | t += length; 377 | } 378 | else { 379 | switch(*p) { 380 | case '"': case '\\': case '/': 381 | *t = *p; break; 382 | case 'b': *t = '\b'; break; 383 | case 'f': *t = '\f'; break; 384 | case 'n': *t = '\n'; break; 385 | case 'r': *t = '\r'; break; 386 | case 't': *t = '\t'; break; 387 | default: assert(0); 388 | } 389 | t++; 390 | p++; 391 | } 392 | } 393 | else 394 | *(t++) = *(p++); 395 | } 396 | *t = '\0'; 397 | lex->token = TOKEN_STRING; 398 | return; 399 | 400 | out: 401 | free(lex->value.string); 402 | } 403 | 404 | static int lex_scan_number(lex_t *lex, char c, json_error_t *error) 405 | { 406 | const char *saved_text; 407 | char *end; 408 | double value; 409 | 410 | lex->token = TOKEN_INVALID; 411 | 412 | if(c == '-') 413 | c = lex_get_save(lex, error); 414 | 415 | if(c == '0') { 416 | c = lex_get_save(lex, error); 417 | if(isdigit(c)) { 418 | lex_unget_unsave(lex, c); 419 | goto out; 420 | } 421 | } 422 | else if(isdigit(c)) { 423 | c = lex_get_save(lex, error); 424 | while(isdigit(c)) 425 | c = lex_get_save(lex, error); 426 | } 427 | else { 428 | lex_unget_unsave(lex, c); 429 | goto out; 430 | } 431 | 432 | if(c != '.' && c != 'E' && c != 'e') { 433 | long value; 434 | 435 | lex_unget_unsave(lex, c); 436 | 437 | saved_text = strbuffer_value(&lex->saved_text); 438 | value = strtol(saved_text, &end, 10); 439 | assert(end == saved_text + lex->saved_text.length); 440 | 441 | if((value == LONG_MAX && errno == ERANGE) || value > INT_MAX) { 442 | error_set(error, lex, "too big integer"); 443 | goto out; 444 | } 445 | else if((value == LONG_MIN && errno == ERANGE) || value < INT_MIN) { 446 | error_set(error, lex, "too big negative integer"); 447 | goto out; 448 | } 449 | 450 | lex->token = TOKEN_INTEGER; 451 | lex->value.integer = (int)value; 452 | return 0; 453 | } 454 | 455 | if(c == '.') { 456 | c = lex_get(lex, error); 457 | if(!isdigit(c)) 458 | goto out; 459 | lex_save(lex, c); 460 | 461 | c = lex_get_save(lex, error); 462 | while(isdigit(c)) 463 | c = lex_get_save(lex, error); 464 | } 465 | 466 | if(c == 'E' || c == 'e') { 467 | c = lex_get_save(lex, error); 468 | if(c == '+' || c == '-') 469 | c = lex_get_save(lex, error); 470 | 471 | if(!isdigit(c)) { 472 | lex_unget_unsave(lex, c); 473 | goto out; 474 | } 475 | 476 | c = lex_get_save(lex, error); 477 | while(isdigit(c)) 478 | c = lex_get_save(lex, error); 479 | } 480 | 481 | lex_unget_unsave(lex, c); 482 | 483 | saved_text = strbuffer_value(&lex->saved_text); 484 | value = strtod(saved_text, &end); 485 | assert(end == saved_text + lex->saved_text.length); 486 | 487 | if(errno == ERANGE && value != 0) { 488 | error_set(error, lex, "real number overflow"); 489 | goto out; 490 | } 491 | 492 | lex->token = TOKEN_REAL; 493 | lex->value.real = value; 494 | return 0; 495 | 496 | out: 497 | return -1; 498 | } 499 | 500 | static int lex_scan(lex_t *lex, json_error_t *error) 501 | { 502 | char c; 503 | 504 | strbuffer_clear(&lex->saved_text); 505 | 506 | if(lex->token == TOKEN_STRING) { 507 | free(lex->value.string); 508 | lex->value.string = NULL; 509 | } 510 | 511 | c = lex_get(lex, error); 512 | while(c == ' ' || c == '\t' || c == '\n' || c == '\r') 513 | { 514 | if(c == '\n') 515 | lex->line++; 516 | 517 | c = lex_get(lex, error); 518 | } 519 | 520 | if(c == (char)EOF) { 521 | if(lex_eof(lex)) 522 | lex->token = TOKEN_EOF; 523 | else 524 | lex->token = TOKEN_INVALID; 525 | goto out; 526 | } 527 | 528 | lex_save(lex, c); 529 | 530 | if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') 531 | lex->token = c; 532 | 533 | else if(c == '"') 534 | lex_scan_string(lex, error); 535 | 536 | else if(isdigit(c) || c == '-') { 537 | if(lex_scan_number(lex, c, error)) 538 | goto out; 539 | } 540 | 541 | else if(isupper(c) || islower(c)) { 542 | /* eat up the whole identifier for clearer error messages */ 543 | const char *saved_text; 544 | 545 | c = lex_get_save(lex, error); 546 | while(isupper(c) || islower(c)) 547 | c = lex_get_save(lex, error); 548 | lex_unget_unsave(lex, c); 549 | 550 | saved_text = strbuffer_value(&lex->saved_text); 551 | 552 | if(strcmp(saved_text, "true") == 0) 553 | lex->token = TOKEN_TRUE; 554 | else if(strcmp(saved_text, "false") == 0) 555 | lex->token = TOKEN_FALSE; 556 | else if(strcmp(saved_text, "null") == 0) 557 | lex->token = TOKEN_NULL; 558 | else 559 | lex->token = TOKEN_INVALID; 560 | } 561 | 562 | else { 563 | /* save the rest of the input UTF-8 sequence to get an error 564 | message of valid UTF-8 */ 565 | lex_save_cached(lex); 566 | lex->token = TOKEN_INVALID; 567 | } 568 | 569 | out: 570 | return lex->token; 571 | } 572 | 573 | static char *lex_steal_string(lex_t *lex) 574 | { 575 | char *result = NULL; 576 | if(lex->token == TOKEN_STRING) 577 | { 578 | result = lex->value.string; 579 | lex->value.string = NULL; 580 | } 581 | return result; 582 | } 583 | 584 | static int lex_init(lex_t *lex, get_func get, eof_func eof, void *data) 585 | { 586 | stream_init(&lex->stream, get, eof, data); 587 | if(strbuffer_init(&lex->saved_text)) 588 | return -1; 589 | 590 | lex->token = TOKEN_INVALID; 591 | lex->line = 1; 592 | 593 | return 0; 594 | } 595 | 596 | static void lex_close(lex_t *lex) 597 | { 598 | if(lex->token == TOKEN_STRING) 599 | free(lex->value.string); 600 | strbuffer_close(&lex->saved_text); 601 | } 602 | 603 | 604 | /*** parser ***/ 605 | 606 | static json_t *parse_value(lex_t *lex, json_error_t *error); 607 | 608 | static json_t *parse_object(lex_t *lex, json_error_t *error) 609 | { 610 | json_t *object = json_object(); 611 | if(!object) 612 | return NULL; 613 | 614 | lex_scan(lex, error); 615 | if(lex->token == '}') 616 | return object; 617 | 618 | while(1) { 619 | char *key; 620 | json_t *value; 621 | 622 | if(lex->token != TOKEN_STRING) { 623 | error_set(error, lex, "string or '}' expected"); 624 | goto error; 625 | } 626 | 627 | key = lex_steal_string(lex); 628 | if(!key) 629 | return NULL; 630 | 631 | lex_scan(lex, error); 632 | if(lex->token != ':') { 633 | free(key); 634 | error_set(error, lex, "':' expected"); 635 | goto error; 636 | } 637 | 638 | lex_scan(lex, error); 639 | value = parse_value(lex, error); 640 | if(!value) { 641 | free(key); 642 | goto error; 643 | } 644 | 645 | if(json_object_set_nocheck(object, key, value)) { 646 | free(key); 647 | json_decref(value); 648 | goto error; 649 | } 650 | 651 | json_decref(value); 652 | free(key); 653 | 654 | lex_scan(lex, error); 655 | if(lex->token != ',') 656 | break; 657 | 658 | lex_scan(lex, error); 659 | } 660 | 661 | if(lex->token != '}') { 662 | error_set(error, lex, "'}' expected"); 663 | goto error; 664 | } 665 | 666 | return object; 667 | 668 | error: 669 | json_decref(object); 670 | return NULL; 671 | } 672 | 673 | static json_t *parse_array(lex_t *lex, json_error_t *error) 674 | { 675 | json_t *array = json_array(); 676 | if(!array) 677 | return NULL; 678 | 679 | lex_scan(lex, error); 680 | if(lex->token == ']') 681 | return array; 682 | 683 | while(lex->token) { 684 | json_t *elem = parse_value(lex, error); 685 | if(!elem) 686 | goto error; 687 | 688 | if(json_array_append(array, elem)) { 689 | json_decref(elem); 690 | goto error; 691 | } 692 | json_decref(elem); 693 | 694 | lex_scan(lex, error); 695 | if(lex->token != ',') 696 | break; 697 | 698 | lex_scan(lex, error); 699 | } 700 | 701 | if(lex->token != ']') { 702 | error_set(error, lex, "']' expected"); 703 | goto error; 704 | } 705 | 706 | return array; 707 | 708 | error: 709 | json_decref(array); 710 | return NULL; 711 | } 712 | 713 | static json_t *parse_value(lex_t *lex, json_error_t *error) 714 | { 715 | json_t *json; 716 | 717 | switch(lex->token) { 718 | case TOKEN_STRING: { 719 | json = json_string_nocheck(lex->value.string); 720 | break; 721 | } 722 | 723 | case TOKEN_INTEGER: { 724 | json = json_integer(lex->value.integer); 725 | break; 726 | } 727 | 728 | case TOKEN_REAL: { 729 | json = json_real(lex->value.real); 730 | break; 731 | } 732 | 733 | case TOKEN_TRUE: 734 | json = json_true(); 735 | break; 736 | 737 | case TOKEN_FALSE: 738 | json = json_false(); 739 | break; 740 | 741 | case TOKEN_NULL: 742 | json = json_null(); 743 | break; 744 | 745 | case '{': 746 | json = parse_object(lex, error); 747 | break; 748 | 749 | case '[': 750 | json = parse_array(lex, error); 751 | break; 752 | 753 | case TOKEN_INVALID: 754 | error_set(error, lex, "invalid token"); 755 | return NULL; 756 | 757 | default: 758 | error_set(error, lex, "unexpected token"); 759 | return NULL; 760 | } 761 | 762 | if(!json) 763 | return NULL; 764 | 765 | return json; 766 | } 767 | 768 | static json_t *parse_json(lex_t *lex, json_error_t *error) 769 | { 770 | error_init(error); 771 | 772 | lex_scan(lex, error); 773 | if(lex->token != '[' && lex->token != '{') { 774 | error_set(error, lex, "'[' or '{' expected"); 775 | return NULL; 776 | } 777 | 778 | return parse_value(lex, error); 779 | } 780 | 781 | typedef struct 782 | { 783 | const char *data; 784 | int pos; 785 | } string_data_t; 786 | 787 | static int string_get(void *data) 788 | { 789 | char c; 790 | string_data_t *stream = (string_data_t *)data; 791 | c = stream->data[stream->pos]; 792 | if(c == '\0') 793 | return EOF; 794 | else 795 | { 796 | stream->pos++; 797 | return c; 798 | } 799 | } 800 | 801 | static int string_eof(void *data) 802 | { 803 | string_data_t *stream = (string_data_t *)data; 804 | return (stream->data[stream->pos] == '\0'); 805 | } 806 | 807 | json_t *json_loads(const char *string, json_error_t *error) 808 | { 809 | lex_t lex; 810 | json_t *result; 811 | 812 | string_data_t stream_data = { 813 | .data = string, 814 | .pos = 0 815 | }; 816 | 817 | if(lex_init(&lex, string_get, string_eof, (void *)&stream_data)) 818 | return NULL; 819 | 820 | result = parse_json(&lex, error); 821 | if(!result) 822 | goto out; 823 | 824 | lex_scan(&lex, error); 825 | if(lex.token != TOKEN_EOF) { 826 | error_set(error, &lex, "end of file expected"); 827 | json_decref(result); 828 | result = NULL; 829 | } 830 | 831 | out: 832 | lex_close(&lex); 833 | return result; 834 | } 835 | 836 | json_t *json_loadf(FILE *input, json_error_t *error) 837 | { 838 | lex_t lex; 839 | json_t *result; 840 | 841 | if(lex_init(&lex, (get_func)fgetc, (eof_func)feof, input)) 842 | return NULL; 843 | 844 | result = parse_json(&lex, error); 845 | if(!result) 846 | goto out; 847 | 848 | lex_scan(&lex, error); 849 | if(lex.token != TOKEN_EOF) { 850 | error_set(error, &lex, "end of file expected"); 851 | json_decref(result); 852 | result = NULL; 853 | } 854 | 855 | out: 856 | lex_close(&lex); 857 | return result; 858 | } 859 | 860 | json_t *json_load_file(const char *path, json_error_t *error) 861 | { 862 | json_t *result; 863 | FILE *fp; 864 | 865 | error_init(error); 866 | 867 | fp = fopen(path, "r"); 868 | if(!fp) 869 | { 870 | error_set(error, NULL, "unable to open %s: %s", 871 | path, strerror(errno)); 872 | return NULL; 873 | } 874 | 875 | result = json_loadf(fp, error); 876 | 877 | fclose(fp); 878 | return result; 879 | } 880 | --------------------------------------------------------------------------------