/* format a cyberflex card */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "scrw.h"

#define ISIZE 16
#define INREC  8 /* default number of entries, override with -n */

int vflag;

main(ac, av)
int ac;
char *av[];
{
    int port = 0, r1, r2, fd, n, err, i, inrec = INREC;
    unsigned char buf[32];
    static unsigned char key[8] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
    static unsigned char create_buf[16] = {0x00, 0x00, 0x2e, 0x69, 0x02, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    char zero_buf[ISIZE];
    static unsigned char DOT_I[2] = {0x2e, 0x69};
    unsigned char cla = 0x00; 

    while ((i = getopt(ac, av, "12n:v")) != -1) {
	switch (i) {
	case '1':
	case '2':
	    port = i - '1';
	    break;
	case 'n':
	    inrec = atoi(optarg);
	    break;
	case 'v':
	    vflag = 1;
	    break;
	default:
	case 'h':
	    printf ("Usage: sformat [-12] [-n #entries] [-v (verbose)]\n");
	    exit (1);
	}
    }

    fd = scopen(port, SCODSR, NULL);
    if (fd < 0) {
	printf("can't open reader\n");
	exit(1);
    }
    n = screset(fd, buf, &err);
    if (!n) {
	printf("%s\n", scerrtab[err]);
	exit(2);
    }

    /* fill in file size */
    n = ISIZE * inrec + 16;
    create_buf[0] = n >> 8;
    create_buf[1] = n & 0xff;

    /* verify AUT0 */
  try_again:
    scwrite(fd, cla, 0x2a, 0x00, 0x00, 0x08, key, &r1, &r2);
    if (vflag)
	printf("verify_key: smartcard returns %x %x\n", r1, r2);
    if (r1 == 0x6d && r2 == 0x00) {
      cla = 0xf0;
      goto try_again; 
    }

    /* remove old .i */
    scwrite(fd, cla, 0xe4, 0x00, 0x00, 2, DOT_I, &r1, &r2);
    if (r1 == 0x90)
	printf("removed old .i\n");

    /* create .i */
    scwrite(fd, cla, 0xe0, 0, 0, 0x10, create_buf, &r1, &r2);
    if (vflag)
	printf("create_file: smartcard returns %x %x\n", r1, r2);

    /* select .i */
    scwrite(fd, cla, 0xa4, 0x00, 0x00, 0x02, DOT_I, &r1, &r2);
    if (vflag)
	printf("select_file: smartcard returns %x %x\n", r1, r2);
  
    /* write 0s to .i */
    for (i=0; i<ISIZE; i++)
	zero_buf[i] = 0;
    for (i=0; i<inrec; i++)
	scwrite(fd, cla, 0xd6, 0x00, i * ISIZE, ISIZE, zero_buf, &r1, &r2);
    if (vflag)
	printf("update_binary: smartcard returns %x %x\n", r1, r2);
  
    scclose(fd);
}
