Commit a1b17229b8059ef89ae6a8d64b4fbae528a9ead2

Con Kolivas 2012-09-26T15:23:01

Initiate stratum and grab first json result.

diff --git a/cgminer.c b/cgminer.c
index 000782c..63412c1 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -557,6 +557,8 @@ static char *set_url(char *arg)
 	if (!extract_sockaddr(pool, arg))
 		return "Failed to extract address from parsed url";
 
+	initiate_stratum(pool);
+
 	opt_set_charp(arg, &pool->rpc_url);
 	if (strncmp(arg, "http://", 7) &&
 	    strncmp(arg, "https://", 8)) {
diff --git a/util.c b/util.c
index 6ac8064..79c7e8f 100644
--- a/util.c
+++ b/util.c
@@ -845,3 +845,96 @@ bool extract_sockaddr(struct pool *pool, char *url)
 	pool->server = (struct sockaddr_in *)res->ai_addr;
 	return true;
 }
+
+static bool sock_send(int sock, char *s, ssize_t len)
+{
+	size_t sent = 0;
+
+	while (len > 0 ) {
+		sent = send(sock, s + sent, len, 0);
+		if (sent < 1)
+			return false;
+		len -= sent;
+	}
+	fsync(sock);
+
+	return true;
+}
+
+#define RECVSIZE 8192
+
+bool initiate_stratum(struct pool *pool)
+{
+	json_t *val, *res_val, *err_val;
+	struct timeval timeout;
+	char *s, *ret = NULL;
+	json_error_t err;
+	ssize_t len;
+	fd_set rd;
+
+	s = alloca(RECVSIZE);
+	sprintf(s, "{\"id\": 0, \"method\": \"mining.subscribe\", \"params\": []}\n");
+
+	pool->sock = socket(AF_INET, SOCK_STREAM, 0);
+	if (pool->sock == INVSOCK)
+		quit(1, "Failed to create pool socket in initiate_stratum");
+	if (SOCKETFAIL(connect(pool->sock, (struct sockaddr *)pool->server, sizeof(struct sockaddr)))) {
+		applog(LOG_DEBUG, "Failed to connect socket to pool");
+		return false;
+	}
+
+	if (!sock_send(pool->sock, s, strlen(s))) {
+		applog(LOG_DEBUG, "Failed to send s in initiate_stratum");
+		return false;
+	}
+
+	/* Use select to timeout instead of waiting forever for a response */
+	FD_ZERO(&rd);
+	FD_SET(pool->sock, &rd);
+	timeout.tv_sec = 60;
+	if (select(pool->sock + 1, &rd, NULL, NULL, &timeout) < 1) {
+		applog(LOG_DEBUG, "Timed out waiting for response in initiate_stratum");
+		return false;
+	}
+
+	if (recv(pool->sock, s, RECVSIZE, MSG_PEEK | MSG_DONTWAIT) < 1) {
+		applog(LOG_DEBUG, "Failed to recv sock in initiate_stratum");
+		return false;
+	}
+
+	ret = strtok(s, "\n");
+	if (!ret) {
+		applog(LOG_DEBUG, "Failed to parse a \\n terminated string in initiate_stratum");
+		return false;
+	}
+
+	len = strlen(ret);
+	read(pool->sock, s, len);
+
+	val = JSON_LOADS(s, &err);
+	if (!val) {
+		applog(LOG_DEBUG, "JSON decode failed(%d): %s", err.line, err.text);
+		return false;
+	}
+
+	res_val = json_object_get(val, "result");
+	err_val = json_object_get(val, "error");
+
+	if (!res_val || json_is_null(res_val) ||
+	    (err_val && !json_is_null(err_val))) {
+		char *ss;
+
+		if (err_val)
+			ss = json_dumps(err_val, JSON_INDENT(3));
+		else
+			ss = strdup("(unknown reason)");
+
+		applog(LOG_INFO, "JSON-RPC call failed: %s", ss);
+
+		free(ss);
+
+		return false;
+	}
+
+	return true;
+}
diff --git a/util.h b/util.h
index c99ecfd..72304fe 100644
--- a/util.h
+++ b/util.h
@@ -110,5 +110,6 @@
 #endif
 struct pool;
 bool extract_sockaddr(struct pool *pool, char *url);
+bool initiate_stratum(struct pool *pool);
 
 #endif /* __UTIL_H__ */