copyloop.c 4.78 KB
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <bbcard.h>

#define	BB_FL_BLOCK_SIZE	0x4000	/* 16KB */

#define MIN(x,y) (((x) < (y)) ? (x) : (y))

char *pname;
char *dname = "/dev/usb/bbrdb0";
char *uname = "user.sys";
char *tname = "tix.sys";

static void
write_tickets(BBCHandle h)
{
	struct stat sb;
	int fd, rv;
	char *buf, *rbuf;
	int len, rlen;

	buf = NULL;
	if (stat(tname, &sb) >= 0) {
		len = sb.st_size;
		if ((fd = open(tname, O_RDONLY)) >= 0) {
			if ((buf = malloc(len)) == NULL) {
				perror("malloc");
				exit(1);
			}
			read(fd, buf, len);
			rv = BBCStoreTickets(h, buf, len);
			printf("%d: BBCStoreTickets returns %d\n", getpid(), rv);
		}
	}

	rbuf = NULL;
	if ((rv = BBCTicketsSize(h)) < 0)
		printf("%d: BBCTicketsSize returns %d\n", getpid(), rv);
	else {
		printf("%d: BBCTicketsSize %d\n", getpid(), rv);
		rlen = rv;
		if ((rbuf = malloc(rlen)) == NULL) {
			perror("malloc");
			exit(1);
		}
		rv = BBCGetTickets(h, rbuf, rlen);
		printf("%d: BBCGetTickets returns %d\n", getpid(), rv);
	}

	if (buf != NULL && rbuf != NULL) {
		if (len != rlen)
			printf("%d: Ticket length miscompare (%d != %d)\n", 
				getpid(), len, rlen);
		if (memcmp(buf, rbuf, MIN(len,rlen))) {
			printf("%d: Tickets miscompare!\n", getpid());
			exit(1);
		}
	
	}

	if (buf != NULL) free(buf);
	if (rbuf != NULL) free(rbuf);
}

static void
write_userdata(h)
{
	struct stat sb;
	int fd, rv;
	char *buf, *rbuf;
	int len, rlen;

	buf = NULL;
	if (stat(uname, &sb) >= 0) {
		len = sb.st_size;
		if ((fd = open(uname, O_RDONLY)) >= 0) {
			if ((buf = malloc(len)) == NULL) {
				perror("malloc");
				exit(1);
			}
			read(fd, buf, len);
			rv = BBCStoreUserData(h, buf, len);
			printf("%d: BBCStoreUserData returns %d\n", getpid(), rv);
		}
	}

	rbuf = NULL;
	if ((rv = BBCUserDataSize(h)) < 0)
		printf("%d: BBCUserDataSize returns %d\n", getpid(), rv);
	else {
		printf("%d: BBCUserDataSize %d\n", getpid(), rv);
		rlen = rv;
		if ((rbuf = malloc(rlen)) == NULL) {
			perror("malloc");
			exit(1);
		}
		rv = BBCGetUserData(h, rbuf, rlen);
		printf("%d: BBCGetUserData returns %d\n", getpid(), rv);
	}

	if (buf != NULL && rbuf != NULL) {
		if (len != rlen)
			printf("%d: Userdata length miscompare (%d != %d)\n", 
				getpid(), len, rlen);
		if (memcmp(buf, rbuf, MIN(len,rlen))) {
			printf("%d: Userdata miscompare!\n", getpid());
			exit(1);
		}
	
	}
	if (buf != NULL) free(buf);
	if (rbuf != NULL) free(rbuf);
}

static void
do_fork_child()
{
	BBCHandle h;
	int rv;
	int bbid;
	int pid;

	if ((pid = fork()) == 0) {
		printf("%d: in child process\n", getpid());
		h = BBCInit(dname, BBC_SYNC);
		printf("%d: BBCInit(%s) returns %d\n", getpid(), dname, h);
		rv = BBCSetLed(h, BBC_LED_ORANGE);
		bbid = 0x1234abcd;
		printf("%s: BBCStoreIdentity ", pname);
		rv = BBCStoreIdentity(h, bbid, NULL, 0);
		printf("returns %d\n", rv);
		write_tickets(h);
		write_userdata(h);
		rv = BBCClose(h);
		printf("%d: BBCClose returns %d\n", getpid(), rv);
		exit(0);
	}
	if (pid < 0) {
		perror("fork");
		return;
	}
	/*
	 * Parent just waits around ...
	 */
	printf("%s: wait for pid %d\n", pname, pid);
	while (1) {
		rv = waitpid(pid, NULL, 0);
		printf("%s: waitpid returns %d\n", pname, rv);
		if (rv == pid)
			break;
		if (rv < 0) {
			perror("waitpid");
			break;
		}
		/* parent gets testy after a while ... */
		printf("%s: wait ret 0, kill pid %d\n", pname, pid);
		kill(pid, SIGKILL);
	}
	return;
}

int
main(int argc, char **argv)
{
	BBCHandle h;
	int rv;
	char *idbuf;
	int idlen;
	int bbid;
	int this_card_done;

	pname = argv[0];

	if (argc > 1)
		dname = argv[argc - 1];

	idlen = BB_FL_BLOCK_SIZE;
	if ((idbuf = malloc(idlen)) == NULL) {
		perror("malloc");
		exit(1);
	}
	setbuf(stdout, NULL);
	setbuf(stderr, NULL);

	this_card_done = 0;
	while (1) {
		sleep(1);
		printf("%s: BBCInit(%s) ", pname, dname);
		fflush(stdout);
		h = BBCInit(dname, BBC_SYNC);
		printf("returns %d\n", h);
		if (h < 0) continue;
		rv = BBCSetLed(h, BBC_LED_GREEN);
		printf("%s: BBCGetIdentity ", pname);
		if ((rv = BBCGetIdentity(h, &bbid, idbuf, idlen)) < 0)
			printf("returns %d\n", rv);
		else
			printf("returns %d bbid 0x%x\n", rv, bbid);
		if (!this_card_done) {
			rv = BBCSetLed(h, BBC_LED_OFF);
			rv = BBCClose(h);
			printf("%s: BBCClose returns %d\n", pname, rv);
			do_fork_child();
			/* Now wait for a card change */
			this_card_done = 1;
			continue;
		}
		if (rv == BBC_CARDCHANGE || rv == BBC_NOCARD || rv == BBC_NOFORMAT) {
			this_card_done = 0;
			printf("%s: got new card\n", pname);
		}
		rv = BBCSetLed(h, BBC_LED_OFF);
		printf("%s: BBCSetLed returns %d\n", pname, rv);
		rv = BBCClose(h);
		printf("%s: BBCClose returns %d\n", pname, rv);
	}

	exit(0);
}