/*
    scfs.h
    Included in scfs.c
    NI, 5/29, 1998

    Modified, Nov. 25, 2000
    Now SCFS is reimplemented as a NFS V2 daemon for better portability. 
    Naomaru Itoi (itoi@eecs.umich.edu)
*/

#ifndef _SCFS_H_
#define _SCFS_H_

#include "nfsproto.h"
#include "admproto.h"

/* Constants */
#define DIRENT_LEN 1024

#define SCFS_IS_NOT_RECORD	0
#define SCFS_IS_RECORD		1

#define ROOT_FID                1 /* it's always 1. */
#define MAXENTRIES 128          /* max number of file entries per directory */


/*#define DIRENT_FILE0		0x2e
  #define DIRENT_FILE1		0x69*/

#define MaxPINLen  8

/* Constants for mount */
#define FLAG_NOT_MOUNTED 0
#define FLAG_MOUNTED 1

/* for scfs_init(), scfs_mount() */
#define FILE_OPEN		 1
#define NO_FILE_OPEN		 0

/* for scfs.c */
#define FILE_NAME_LEN	2
#define DOTI_LEN 16
#define MAX_CHILDREN	8 /* 8 children per directory */
/*#define NI_ALLVALID	XA_V_MODE | XA_V_NLINK | XA_V_SIZE | XA_V_UID | XA_V_GID | XA_V_ATIME | XA_V_MTIME | XA_V_CTIME | XA_V_FILEID | XA_V_TYPE*/
#define SC_MAX_LEN 0xff

/* for scdir.c */
#define Separator		".,:; \t\n\0"
#define MAX_FILE_ENTRIES        256
#define MAX_DEPTH		128
#define STR_ATR			"ATR"
#define STR_CARDNAME		"CARDNAME"
#define STR_MULTIFLEXPIN	"MULTIFLEXPIN"
#define STR_MULTIFLEXGETRES	"MULTIFLEXGETRES"
#define STR_DIR			"DIR"
#define STR_DEFAULT		"CLA_DEFAULT"
#define STR_VERIFYKEY		"CLA_VERIFYKEY"
#define STR_VERIFYPIN		"CLA_VERIFYPIN"
#define STR_READBINARY		"CLA_READBINARY"
#define STR_UPDATEBINARY	"CLA_UPDATEBINARY"
#define STR_CREATE		"CLA_CREATE"
#define STR_DELETEFILE		"CLA_DELETEFILE"
#define STR_READRECORD		"CLA_READRECORD"
#define STR_UPDATERECORD	"CLA_UPDATERECORD"
#define STR_SELECT		"SELECT"
#define STR_INAUTH		"INAUTH"
#define STR_EXAUTH		"EXAUTH"
#define STR_GETRESPONSE		"GETRESPONSE"
#define STR_GETCHALLENGE	"GETCHALLENGE"
#define STR_HASRECORD		"HASRECORD"
#define STR_CREATETYPE		"CREATE_TYPE"
#define CLA_NOSUPP		-1
#define CLA_UNDEFINED		-2
#define SCDFILE		"/etc/scfs.scdb"
#define CREATE_TYPE_MULTIFLEX	0
#define CREATE_TYPE_CYBERFLEXACCESS	1

typedef struct file_ent_str {
    unsigned int fid;         /* file ID */
    unsigned char name[2];    /* 2 byte name */
    /* file type */
    enum file_type {           
	SCFS_TYPE_NULL=0,     /* 0, nothing */
	SCFS_TYPE_ELFILE,     /* 1, elementry file */
	SCFS_TYPE_RECFILE,    /* 2, record file */
	SCFS_TYPE_DIR         /* 3, directory */
    } type;  
    unsigned short p_size;    /* physical length of the file */
    unsigned short l_size;    /* logical length of the file */
    struct file_ent_str *parent;
    struct file_ent_str *child[MAX_CHILDREN + 1]; /* +1 for .i */
    int num_children;
} file_ent;

/*
struct scfs_response {
    int size;
    int read_PIN_protected;
    int write_PIN_protected;
    };*/

/* Smartcard configuration data structure */
struct scconfig_str {
    char name[256];	/* name, e.g. "MultiFlex" or "PayFlex" */
    int multiflexpin;	/* 1 if it has MultiFlex type PIN.  0 otherwise */
    int multiflexgetres;	/* 1 if it has MultiFlex type getresponse.  0 otherwise */
    file_ent *file_entries[MAX_FILE_ENTRIES];	/* pointer to a directory structure */
    int cla_default;	/* 1 byte CLA code */
    int cla_verifykey;
    /* 1 byte CLA, -1 if not supported, or -2 if undefined */
    int cla_verifypin;    /* same as cla_verifykey */
    int cla_select;	/* same as cla_verifykey */
    int cla_readbinary;	/* same as cla_verifykey */
    int cla_updatebinary; /* same as cla_verifykey */
    int cla_create;	/* same as cla_verifykey */
    int cla_deletefile;	/* same as cla_verifykey */
    int cla_remove;	/* same as cla_verifykey */	
    int cla_readrecord;	/* same as cla_verifykey */
    int cla_updaterecord; /* same as cla_verifykey */
    int cla_inauth;	/* same as cla_verifykey */
    int cla_exauth;	/* same as cla_verifykey */
    int cla_getresponse;	/* same as cla_verifykey */
    int cla_getchallenge;	/* same as cla_verifykey */
    int num_entries;
    int create_type;
};

/* Function Prototypes */
/* scdir.c */
file_ent *fid_to_fe(u_long fid);
file_ent *new_file_ent (unsigned char *name, enum file_type type,
			file_ent *parent); 
/* scfs.c */
diropres *scfs_lookup (diropargs *ap);
attrstat *scfs_getattr (nfs_fh *ap); 
readdirres *scfs_readdir (readdirargs *ap);
readres *scfs_read (readargs *ap);
attrstat *scfs_write (writeargs *ap);
attrstat *scfs_setattr (sattrargs *ap);
cfsstat *scfs_verify (scfs_verify_args *ap); 
diropres *scfs_create (createargs *ap, enum file_type type);
nfsstat *scfs_remove (diropargs *ap, enum file_type type); 
/*
// for scfs.c 
int scfs_init(int port, int flag); 
int scfs_mount (int port, char *buf, int flag);
int scfs_unmount ();
int scfs_open_file();
int open_file(int fd, int f0, int f1);
int a2h(char c, char d, unsigned char *f);
int scfs_read(unsigned char *fid, int offset, int length, unsigned char *buf, int rec_flag, unsigned char *parent_fid, dev_t t_dev);
int scfs_write(unsigned char *fid, int offset, int length, char *buf, int rec_flag, unsigned char *parent_fid, dev_t t_dev);
int scfs_remove(xfs_handle parent_fid, char *name);
int scfs_rmdir(xfs_handle parent_fid, char *name);
int scfs_rename(xfs_handle old_parent_fid, char *old_name,
		xfs_handle new_parent_fid, char *new_name,
		dev_t t_dev);
int name_to_fid(xfs_handle parent_fid, char *name, xfs_handle *child_fid);
int scfs_update_dirent(struct scdnode *node);
int scfs_add_dirent(struct scdnode *parent_node, struct scdnode *new_node);
int find_child_in_parent(struct scdnode *parent_node, struct scdnode *child_node);
int update_ith_dirent(struct scdnode *parent_node, int ith, struct fileent *fe);
int remove_node(struct scdnode *parent_node, unsigned char *child_fid);
int scfs_verifypin(int insize, char *pin);
int scfs_verifykey(int fd, struct xfs_message_pioctl *h, u_int size);
int scfs_inauth(int keynum, int insize, char *pin);
int scfs_getresponse(char *str, int outsize);
int scfs_exauth(int keynum, int insize, char *response);
int scfs_getchallenge(char *str, int outsize);
int scfs_tcl_readpin(char *pin);
int scfs_query_file(struct scfs_response *scfs_res, struct scdnode *node);
int godown(struct scdnode *node);

// for scdir.c
int scdir_init(unsigned char *atr, char *filename);
struct scdnode *get_scdnode(unsigned char *);
struct scdnode *new_scdnode(struct fileent *fe, struct scdnode *parent);
void print_path (struct scdnode *);
int name2fid (char *name, unsigned char *fid, int *recnum);
int scfs_getdirent(unsigned char *fid, unsigned char *parent_fid, char *dirent);
int config_smartcard(FILE *fd, int *line);
void scconfig_setdefault(struct scconfig *scc);
int isyes(char *str);
void print_scconfig(struct scconfig *scc);
int scdir_installroot();
int new_dir(struct scdnode *node);
int scdir_free();
int free_dir(struct scdnode *node);
struct scdnode *add_node(struct scdnode *parent_node, char *file_name, int type, int size);
*/

#endif /* _SCFS_H_ */
