Commit c33553d5a65556a4802bea6ec251e7aa80b809d5

Kano 2011-12-03T00:29:33

C sample api code

diff --git a/api-example.c b/api-example.c
new file mode 100755
index 0000000..9cb0416
--- /dev/null
+++ b/api-example.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2011 Kano
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "compat.h"
+#include "miner.h"
+
+#if defined(unix)
+	#include <errno.h>
+	#include <sys/socket.h>
+	#include <netinet/in.h>
+	#include <arpa/inet.h>
+	#include <netdb.h>
+
+	#define SOCKETTYPE int
+	#define SOCKETFAIL(a) ((a) < 0)
+	#define INVSOCK -1
+	#define CLOSESOCKET close
+
+	#define SOCKETINIT {}
+
+	#define SOCKERRMSG strerror(errno)
+#endif
+
+#ifdef WIN32
+	#include <winsock2.h>
+	#include "inet_ntop.h"
+	#include "inet_pton.h"
+
+	#define SOCKETTYPE SOCKET
+	#define SOCKETFAIL(a) ((a) == SOCKET_ERROR)
+	#define INVSOCK INVALID_SOCKET
+	#define CLOSESOCKET closesocket
+
+	static char WSAbuf[1024];
+
+	struct WSAERRORS {
+		int id;
+		char *code;
+	} WSAErrors[] = {
+		{ 0,			"No error" },
+		{ WSAEINTR,		"Interrupted system call" },
+		{ WSAEBADF,		"Bad file number" },
+		{ WSAEACCES,		"Permission denied" },
+		{ WSAEFAULT,		"Bad address" },
+		{ WSAEINVAL,		"Invalid argument" },
+		{ WSAEMFILE,		"Too many open sockets" },
+		{ WSAEWOULDBLOCK,	"Operation would block" },
+		{ WSAEINPROGRESS,	"Operation now in progress" },
+		{ WSAEALREADY,		"Operation already in progress" },
+		{ WSAENOTSOCK,		"Socket operation on non-socket" },
+		{ WSAEDESTADDRREQ,	"Destination address required" },
+		{ WSAEMSGSIZE,		"Message too long" },
+		{ WSAEPROTOTYPE,	"Protocol wrong type for socket" },
+		{ WSAENOPROTOOPT,	"Bad protocol option" },
+		{ WSAEPROTONOSUPPORT,	"Protocol not supported" },
+		{ WSAESOCKTNOSUPPORT,	"Socket type not supported" },
+		{ WSAEOPNOTSUPP,	"Operation not supported on socket" },
+		{ WSAEPFNOSUPPORT,	"Protocol family not supported" },
+		{ WSAEAFNOSUPPORT,	"Address family not supported" },
+		{ WSAEADDRINUSE,	"Address already in use" },
+		{ WSAEADDRNOTAVAIL,	"Can't assign requested address" },
+		{ WSAENETDOWN,		"Network is down" },
+		{ WSAENETUNREACH,	"Network is unreachable" },
+		{ WSAENETRESET,		"Net connection reset" },
+		{ WSAECONNABORTED,	"Software caused connection abort" },
+		{ WSAECONNRESET,	"Connection reset by peer" },
+		{ WSAENOBUFS,		"No buffer space available" },
+		{ WSAEISCONN,		"Socket is already connected" },
+		{ WSAENOTCONN,		"Socket is not connected" },
+		{ WSAESHUTDOWN,		"Can't send after socket shutdown" },
+		{ WSAETOOMANYREFS,	"Too many references, can't splice" },
+		{ WSAETIMEDOUT,		"Connection timed out" },
+		{ WSAECONNREFUSED,	"Connection refused" },
+		{ WSAELOOP,		"Too many levels of symbolic links" },
+		{ WSAENAMETOOLONG,	"File name too long" },
+		{ WSAEHOSTDOWN,		"Host is down" },
+		{ WSAEHOSTUNREACH,	"No route to host" },
+		{ WSAENOTEMPTY,		"Directory not empty" },
+		{ WSAEPROCLIM,		"Too many processes" },
+		{ WSAEUSERS,		"Too many users" },
+		{ WSAEDQUOT,		"Disc quota exceeded" },
+		{ WSAESTALE,		"Stale NFS file handle" },
+		{ WSAEREMOTE,		"Too many levels of remote in path" },
+		{ WSASYSNOTREADY,	"Network system is unavailable" },
+		{ WSAVERNOTSUPPORTED,	"Winsock version out of range" },
+		{ WSANOTINITIALISED,	"WSAStartup not yet called" },
+		{ WSAEDISCON,		"Graceful shutdown in progress" },
+		{ WSAHOST_NOT_FOUND,	"Host not found" },
+		{ WSANO_DATA,		"No host data of that type was found" },
+		{ -1,			"Unknown error code" }
+	};
+
+	static char *WSAErrorMsg()
+	{
+		char *msg;
+		int i;
+		int id = WSAGetLastError();
+
+		/* Assume none of them are actually -1 */
+		for (i = 0; WSAErrors[i].id != -1; i++)
+			if (WSAErrors[i].id == id)
+				break;
+
+		sprintf(WSAbuf, "Socket Error: (%d) %s", id, WSAErrors[i].code);
+
+		return &(WSAbuf[0]);
+	}
+
+	#define SOCKERRMSG WSAErrorMsg()
+
+	static WSADATA WSA_Data;
+
+	#define SOCKETINIT	int wsa; \
+				if (wsa = WSAStartup(0x0202, &WSA_Data)) { \
+					printf("Socket startup failed: %d\n", wsa); \
+					return 1; \
+				}
+
+	#ifndef SHUT_RDWR
+	#define SHUT_RDWR SD_BOTH
+	#endif
+#endif
+
+static const char SEPARATOR = '|';
+static const char COMMA = ',';
+static const char EQ = '=';
+
+void display(char *buf)
+{
+	char *nextobj, *item, *nextitem, *eq;
+	int itemcount;
+
+	while (buf != NULL) {
+		nextobj = strchr(buf, SEPARATOR);
+		if (nextobj != NULL)
+			*(nextobj++) = '\0';
+
+		if (*buf) {
+			item = buf;
+			itemcount = 0;
+			while (item != NULL) {
+				nextitem = strchr(item, COMMA);
+				if (nextitem != NULL)
+					*(nextitem++) = '\0';
+
+				if (*item) {
+					eq = strchr(item, EQ);
+					if (eq != NULL)
+						*(eq++) = '\0';
+
+					if (itemcount == 0)
+						printf("[%s%s] =>\n(\n", item, (eq != NULL && isdigit(*eq)) ? eq : "");
+
+					if (eq != NULL)
+						printf("   [%s] => %s\n", item, eq);
+					else
+						printf("   [%d] => %s\n", itemcount, item);
+				}
+
+				item = nextitem;
+				itemcount++;
+			}
+			if (itemcount > 0)
+				puts(")");
+		}
+
+		buf = nextobj;
+	}
+}
+
+int callapi(char *command, char *host, short int port)
+{
+	char buf[BUFSIZ];
+	struct hostent *ip;
+	struct sockaddr_in serv;
+	SOCKETTYPE sock;
+	int ret = 0;
+	int n;
+
+	SOCKETINIT;
+
+	ip = gethostbyname(host);
+
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	if (sock == INVSOCK) {
+		printf("Socket initialisation failed: %s\n", SOCKERRMSG);
+		return 1;
+	}
+
+	memset(&serv, 0, sizeof(serv));
+	serv.sin_family = AF_INET;
+	serv.sin_addr = *((struct in_addr *)ip->h_addr);
+	serv.sin_port = htons(port);
+
+	if (SOCKETFAIL(connect(sock, (struct sockaddr *)&serv, sizeof(struct sockaddr)))) {
+		printf("Socket connect failed: %s\n", SOCKERRMSG);
+		return 1;
+	}
+
+	n = send(sock, command, strlen(command)+1, 0);
+	if (SOCKETFAIL(n)) {
+		printf("Send failed: %s\n", SOCKERRMSG);
+		ret = 1;
+	}
+	else {
+		n = recv(sock, buf, BUFSIZ, 0);
+		buf[n] = '\0';
+
+		printf("Reply was '%s'\n", buf);
+
+		display(buf);
+	}
+
+	CLOSESOCKET(sock);
+
+	return ret;
+}
+
+static char *trim(char *str)
+{
+	char *ptr;
+
+	while (isspace(*str))
+		str++;
+
+	ptr = strchr(str, '\0');
+	while (ptr-- > str) {
+		if (isspace(*ptr))
+			*ptr = '\0';
+	}
+
+	return str;
+}
+
+int main(int argc, char *argv[])
+{
+	char *command = "summary";
+	char *host = "127.0.0.1";
+	short int port = 4028;
+	char *ptr;
+
+	if (argc > 1) {
+		ptr = trim(argv[1]);
+		if (strlen(ptr) > 0)
+			command = ptr;
+	}
+
+	if (argc > 2) {
+		ptr = trim(argv[2]);
+		if (strlen(ptr) > 0)
+			host = ptr;
+	}
+
+	if (argc > 3) {
+		ptr = trim(argv[3]);
+		if (strlen(ptr) > 0)
+			port = atoi(ptr);
+	}
+
+	return callapi(command, host, port);
+}