static    char    sccsid[]="%Z% %M% %I% %E% %U%";
/*******************************************************/
/* <clfuncfile.c>                                      */
/*      func                                           */
/*******************************************************/
#include "colmn.h"

extern CLCOMMON  CLcommon;
extern CLPRTBL   *pCLprocTable;
extern GlobalCt  *pGlobTable;
extern int giOptions[];

/****************************************/
/*										*/
/****************************************/
static int _check_fp(ope,fp,pp)
char ope,**pp;
FILE *fp;
{
	HASHB *hp;
	int i;
	char *p,*argv[2];

	hp = pCLprocTable->pha_fp;
	hp->ha_key = (char *)argv;
	argv[0] = argv[1] = NULL;
	if (ope == 'S') {
		if (pp && (p=*pp)) argv[1] = Strdup(p);
		i = akxshasls(hp,fp);
		if (i<=0 && argv[1]) Free(argv[1]);
	}
	else if (ope == 'R') {
		i = akxshaslr(hp,fp);
		if (i>0 && pp) *pp = argv[1];
	}
	else if (ope == 'D') {
		i = akxshasld(hp,fp);
		if (i > 0) {
			if (pp) *pp = argv[1];
			else if (argv[1]) Free(argv[1]);
		}
	}
	return i;
}

/****************************
struct stat
{
  dev_t         st_dev;			1
  ino_t         st_ino;			2
  mode_t        st_mode;		3
  nlink_t       st_nlink;		4
  uid_t         st_uid;			5
  gid_t         st_gid;			6
  dev_t         st_rdev;		7
  off_t         st_size;		8
  timestruc_t   st_atim;		9,10
  timestruc_t   st_mtim;		11,12
  timestruc_t   st_ctim;		13,14
  blksize_t     st_blksize;		15
  blkcnt_t      st_blocks;		16
  long          st_spare4[2];
};

#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
**********************************/
#define CL_MAX_ST_VAL	17
/****************************************/
/*	stat(file) or fstat(fp)				*/
/****************************************/
static int _func_fpstat(pretval,fname,nparm,pParm,fp)
int  *pretval;
char *fname;
int nparm;
tdtInfoParm *pParm;
FILE *fp;
{
	struct stat tStat;
	int st_val[CL_MAX_ST_VAL];
	tdtInfoParm *pInfoParm,rInfoParm,*ppParm[2];
	tdtInfoParm ***pTBL;
	char c,*name;
	tdtArrayIndex tIndex;
	int  *index,maxargs,nm;
	int  i,ix,ret,f_type;
/*	double dval;	*/
	MPA  mpa;

	if (fname) ret = stat(fname,&tStat);
	else if (fp) ret = fstat(fileno(fp),&tStat);
	else ret = -1;
	if (ret) {
		*pretval = ret;
		return 0;
	}
	*pretval = 0;
	if (S_ISFIFO(tStat.st_mode)) f_type = 1;
	else if (S_ISCHR(tStat.st_mode)) f_type = 2;
	else if (S_ISDIR(tStat.st_mode)) f_type = 3;
	else if (S_ISBLK(tStat.st_mode)) f_type = 4;
	else if (S_ISREG(tStat.st_mode)) f_type = 5;
	else if (S_ISLNK(tStat.st_mode)) f_type = 6;
	else f_type = 0;

	st_val[ 0] = f_type;
	st_val[ 1] = tStat.st_dev;
	st_val[ 2] = tStat.st_ino;
	st_val[ 3] = tStat.st_mode;
	st_val[ 4] = tStat.st_nlink;
	st_val[ 5] = tStat.st_uid;
	st_val[ 6] = tStat.st_gid;
	st_val[ 7] = tStat.st_rdev;
/*	st_val[ 8] = tStat.st_size;	*/
/*	dval = tStat.st_size;	*/
	m_ll2mpa(tStat.st_size,&mpa);
	st_val[ 9] = tStat.st_atim.tv_sec;
	st_val[10] = tStat.st_atim.tv_nsec;
	st_val[11] = tStat.st_mtim.tv_sec;
	st_val[12] = tStat.st_mtim.tv_nsec;
	st_val[13] = tStat.st_ctim.tv_sec;
	st_val[14] = tStat.st_ctim.tv_nsec;
	st_val[15] = tStat.st_blksize;
	st_val[16] = tStat.st_blocks;

	ppParm[0] = &pParm[0];
	ppParm[1] = &pParm[1];
	if (ret=cl_get_ITBL_maxargs(nparm,ppParm,&tIndex,&pTBL,1,CL_MAX_ST_VAL,&maxargs,NULL)) return ret;
	index = tIndex.index;

	nm = X_MIN(CL_MAX_ST_VAL,maxargs);
	ix = index[0];
	for (i=0;i<nm;i++,ix++) {
		pInfoParm = cl_get_array_and_var_ent(&tIndex,pTBL,ix);
		if (pInfoParm) {

DEBUGOUT_InfoParm(194,"_func_stat: i=%d ix=%d",pInfoParm,i,ix);

		/*	if (i == 8) cl_set_parm_double(&rInfoParm,dval);	*/
			if (i == 8) cl_set_parm_mpa(&rInfoParm,&mpa);
			else cl_set_parm_bin(&rInfoParm,st_val[i]);
			if (ret=cl_gx_rep_info_set(pInfoParm,&rInfoParm,1)) return ret;
		}
		else {
			return -1;
		}
	}
	return 0;
}

/****************************************/
/*	fopen(fname, mode)					*/
/*	popen(sh_fname, mode)				*/
/*	opendir(dirname)					*/
/*	unlink(fname)						*/
/****************************************/
static int _func_fopen(pWork,nparm,pParm,ope,iParm)
char *pWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
{
	tdtInfoParm *pInfoParm;
	int iRc,ret,i,retval,len;
	char w1[32],w2[32],*p1,*p2,*func;
	FILE *fp;
	DIR  *dp;

	iRc = 0;
	p1 = w1;
	if ((len = parm_to_char(&pParm[0],&p1,NULL)) >= 0) {
/*
printf("func_file: p1=[%s] ret=%d\n",p1,len);
*/
		if (ope == D_FUC_FOPEN ||	/* fopen(fname,mode) */
		    ope == D_FUC_POPEN ||	/* popen(sh_fname,mode) */
		    ope == D_FUC_OPENDIR) {	/* opendir(dirname) */
			p2 = w2;
			if (nparm >= 2) {
				len = parm_to_char(&pParm[1],&p2,NULL);
/*
printf("func_file: p2=[%s] ret=%d\n",p2,iRc);
*/
			}
			else {
				strcpy(w2,"r");
			}
			if (len >= 0) {
				if (ope == D_FUC_OPENDIR) {
					dp = opendir(p1);
					func = "opendir";
					memcpy(pWork,&dp,sizeof(DIR *));
					fp = (FILE *)dp;
				}
				else {
					if (ope == D_FUC_FOPEN) {
						fp = fopen(p1,p2);
						func = "fopen";
					}
					else {
						fp = popen(p1,p2);
						func = "popen";
					}
					memcpy(pWork,&fp,sizeof(FILE *));
				}
				if (fp) _check_fp('S',fp,&p1);
				else {
				/*
					if (!(pGlobTable->exception = errno))
						pGlobTable->exception = -1;
				*/
					pGlobTable->exception = FILE_OPEN_EXCEPTION + errno;
					pGlobTable->error = -1;
					pGlobTable->err_no = errno;
					ERROROUT5("%s([%s],[%s]) errno=%d %s",func,
					          p1,p2,errno,strerror(errno));
				}
				iParm[0] = DEF_ZOK_BINA;
				iParm[1] = sizeof(FILE *);
			}
		}
		else if (ope == D_FUC_UNLINK ||	/* unlink(fname) */
		         ope == D_FUC_STAT) {	/* stat(fname) */
			retval = 0;
			if (ope == D_FUC_UNLINK) {
				retval = unlink(p1);
				func = "unlink";
			}
			else {
				iRc = _func_fpstat(&retval,p1,nparm-1,pParm+1,NULL);
				func = "stat";
			}
			memcpy(pWork,&retval,sizeof(int));
			if (retval < 0) {
			/*
				if (!(pGlobTable->exception = errno))
					pGlobTable->exception = -1;
			*/
				pGlobTable->exception = FILE_ETC_EXCEPTION + errno;
				pGlobTable->error = -1;
				pGlobTable->err_no = errno;
				ERROROUT4("%s([%s]) errno=%d %s",
				          func,p1,errno,strerror(errno));
			}
		}
	}
	else iRc = -1;

	return iRc;
}

/****************************************/
/*	fclose(fp)							*/
/****************************************/
/********************************************************
S_ISREG(m)	通常のファイルか?
S_ISDIR(m)	ディレクトリか?
S_ISCHR(m)	キャラクター・デバイスか?
S_ISBLK(m)	ブロック・デバイスか?
S_ISFIFO(m)	FIFO (名前付きパイプ) か?
S_ISLNK(m)	シンボリック・リンクか? (POSIX.1-1996 にはない)
S_ISSOCK(m)	ソケットか? (POSIX.1-1996 にはない)

以下のフラグが st_mode フィールド用に定義されている:
S_IFMT   0170000 ファイル種別を示すビット領域を表すビットマスク
S_IFSOCK 0140000 ソケット
S_IFLNK  0120000 シンボリック・リンク
S_IFREG  0100000 通常のファイル
S_IFBLK  0060000 ブロック・デバイス
S_IFDIR  0040000 ディレクトリ
S_IFCHR  0020000 キャラクター・デバイス
S_IFIFO  0010000 FIFO
S_ISUID  0004000 set-user-ID bit
S_ISGID  0002000 set-group-ID bit (下記参照)
S_ISVTX  0001000 スティッキー・ビット (下記参照)
S_IRWXU    00700 ファイル所有者のアクセス許可用のビットマスク
S_IRUSR    00400 所有者の読み込み許可
S_IWUSR    00200 所有者の書き込み許可
S_IXUSR    00100 所有者の実行許可
S_IRWXG    00070 グループのアクセス許可用のビットマスク
S_IRGRP    00040 グループの読み込み許可
S_IWGRP    00020 グループの書き込み許可
S_IXGRP    00010 グループの実行許可
S_IRWXO    00007 他人 (others) のアクセス許可用のビットマスク
S_IROTH    00004 他人の読み込み許可
S_IWOTH    00002 他人の書き込み許可
S_IXOTH    00001 他人の実行許可
*****************************************/

static int _func_close(pWork,ope,fp)
char *pWork;
int  ope;
FILE *fp;
{
	int  retval,rc;
	char *func;
	struct stat tStat;

	if (fp==stdin || fp==stdout || fp==stderr) {
		retval = -1;
	}
	else {
		if ((retval = fileno(fp)) >= 0) {
			retval = fstat(retval,&tStat);
		}
		if (retval < 0) {
			ERROROUT(FORMAT(396));		/* file/pipe/dir用のfpは無効です。 */
		}
		else {
			if (fp) _check_fp('D',fp,NULL);
			if (ope == D_FUC_FCLOSE) {
				if (S_ISREG(tStat.st_mode) || S_ISLNK(tStat.st_mode)) {
					retval = fclose(fp);
					func = "fclose";
					pGlobTable->err_no = errno;
				}
				else {
					ERROROUT("fclose: not file");
					retval = -1;
				}
			}
			else if (ope == D_FUC_PCLOSE) {
				if (S_ISFIFO(tStat.st_mode)) {
					retval = pclose(fp);
					func = "pclose";
					pGlobTable->err_no = errno;
					if (retval == 127) {
						ERROROUT("pclose: sh not executed!");
						pGlobTable->error = retval;
					/*
						pGlobTable->exception = retval;
					*/
						pGlobTable->exception = FILE_CLOSE_EXCEPTION + errno;
					}
				}
				else {
					ERROROUT("pclose: not pipe");
					retval = -1;
				}
			}
			else if (ope == D_FUC_CLOSEDIR) {
				if (S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode)) {
					retval = closedir((DIR *)fp);
					func = "closedir";
					pGlobTable->err_no = errno;
				}
				else {
					ERROROUT("closedir: not directory");
					retval = -1;
				}
			}
			else {
				ERROROUT1("_func_close: invalid ope(%d)!!",ope);
				return -1;
			}
		}
	}
	if (retval < 0) {
	/*	pGlobTable->exception = retval;	*/
		pGlobTable->exception = FILE_CLOSE_EXCEPTION + errno;
		pGlobTable->error = retval;
		ERROROUT3("%s errno=%d %s",func,errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return 0;
}

/****************************************/
/*	fgetline(fp,size,opt)				*/
/****************************************/
static int _func_fgetline(ppWork,nparm,pParm,ope,iParm,fp)
char **ppWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
FILE *fp;
{
	int iRc,ret,size,opt;
	char *pWork,buf[2048];

	pWork = *ppWork;
	/* Get size */
	size = sizeof(buf);
	if (nparm >= 1) {
		if (!cl_is_null_parm(&pParm[0])) {
			if (iRc=cl_get_parm_bin(&pParm[0],&size,"func_file:size:")) return -1;
			size++;
		}
	}
/*
printf("func_file: ope=%d attr=%d size=%d\n",ope,attr,size);
*/
	if (size < 2) {
		ERROROUT1("FGETLINE: size(%d) < 2",size);
		return -1;
	}
	else if (size > sizeof(buf)) {
		if (!(pWork = cl_tmp_const_malloc(size)))
			return ECL_MALLOC_ERROR;
	}
	else pWork = buf;

	/* Get opt */
	opt = 0x02 | 0x04;
	if (nparm >= 2) {
		if (!cl_is_null_parm(&pParm[1])) {
			if (iRc=cl_get_parm_bin(&pParm[1],&opt,"func_file:opt:")) return -1;
		}
	}

	ret = akxa_read_line_opt(pWork,size,fp,opt);
	if (ret < 0) {
		pGlobTable->err_no = errno;
		if (ferror(fp)) {
			pGlobTable->exception = FILE_READ_EXCEPTION + errno;
			ERROROUT2("fgetline: errno=%d %s",errno,strerror(errno));
		}
		else {
			pGlobTable->exception = FILE_READ_END_EXCEPTION;
			ret = ECL_END_OF_FILE;
			ERROROUT("fgetline: end of file");
		}
		pGlobTable->error = ret;
	}
	else {
/*
printf("func_file: ope=%d size=%d ret=%d pWork=[%s]\n",ope,size,ret,pWork);
*/
		if (pWork == buf) {
			if (!(*ppWork = cl_tmp_const_malloc(ret+1)))
				return ECL_MALLOC_ERROR;
			strcpy(*ppWork,pWork);
		}
		else *ppWork = pWork;
	}
	return 0;
}

/****************************************/
/*	fputline(fp,data1,data2,...)		*/
/****************************************/
static int _func_fputline(pWork,nparm,pParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
FILE *fp;
{
	int iRc,ret,i,retval,len,gopt,pos,l,m,n;
	char w1[32],*p1,*p;
	tdtInfoParm *pInfoParm;

	ret = iRc = 0;
	retval = 0;
	for (i=0;i<nparm;i++) {
		p1 = w1;
#if 1
		pInfoParm = &pParm[i];
		if (pInfoParm->pi_id==' ' && pInfoParm->pi_attr==DEF_ZOK_BULK)
			len = parm_to_char(&pParm[i],&p1,NULL);
		else
			len = cl_str_print(&p1,&pParm[i]);
		if (len > 0) {
#else
		if ((len = parm_to_char(&pParm[i],&p1,NULL)) > 0) {
#endif
			p = p1;
			l = len;
			if (giOptions[2] & AKX_NEWLINE_CNV_LF) {
				while ((pos=akxnskipto(p,l,"\r\n")) < l) {
					if ((ret = fwrite(p,pos,1,fp)) < 0) break;
					p += pos;
					if (*p=='\r' && *(p+1)=='\n') m = 2;
					else m = 1;
					if ((n = akxa_log_new_line(fp,giOptions[2])) >= 0) len += n - m;
					p += m;
					l -= pos+m;
				}
			}
			if (ret >= 0) ret = fwrite(p,l,1,fp);
			else {
				ret = -1;
				break;
			}
			retval += len;
		}
		else if (len < 0) {
			iRc = len;
			break;
		}
	}
	pGlobTable->err_no = errno;
	if (ret >= 0) {
		if ((n = akxa_log_new_line(fp,giOptions[2])) >= 0) retval += n;
		pGlobTable->err_no = errno;
	}
	else {
		pGlobTable->error = ret;
	/*	pGlobTable->exception = ret;	*/
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		retval = ret;
		ERROROUT2("fputline: errno=%d %s",errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return iRc;
}

/****************************************/
/*										*/
/****************************************/
static int _get_size_scale(name,nparm,pParm,iParm)
char *name;
tdtInfoParm *pParm;
int nparm,iParm[];
{
	int iRc,attr,size,scale0,scale,dec_size;

	attr   = iParm[0];
	size   = iParm[1];
	scale0 = iParm[2];
	if (nparm >= 1) {
		if (iRc=cl_get_parm_bin(&pParm[0],&size,stradd(name,":size:")))
			return -1;
		if (size<=0 && attr!=DEF_ZOK_DECI) size = iParm[1];
		if (size>0 && attr==DEF_ZOK_FLOA) {
			if (size < 4) {
				ERROROUT3("%s: attr=%d size(%d) is few!!",name,attr,size);
				return -1;
			}
		}
	}
/*
printf("func_file: ope=%d attr=%d size=%d \n",ope,attr,size);
*/
	if (nparm >= 2) {
		if (iRc=cl_get_parm_bin(&pParm[1],&scale0,stradd(name,":scale:")))
			return -1;
	}
	if ((scale=scale0) < 0) scale = -scale;
	if (size>0 && attr!=DEF_ZOK_DECI && size<scale) {
		ERROROUT4("%s:(W) attr=%d size(%d)<scale(%d). set scale=size.",name,attr,size,scale);
		scale = size;
	}
	if (!scale) {
		switch (attr) {
			case DEF_ZOK_BINA:
					if (size > 0) scale = size;
					else scale = sizeof(int);
					break;
			case DEF_ZOK_FLOA:
					if (size > 0) scale = size;
					else scale = sizeof(double);
					break;
			case DEF_ZOK_CHAR:
			case DEF_ZOK_BULK:
			case DEF_ZOK_DATE:
					scale = size;
					break;
		}
	}
	if (attr==DEF_ZOK_BINA) {
		if      (scale >= 8) scale = 8;
		else if (scale >= 4) scale = 4;
		else if (scale >= 2) scale = 2;
	}
	else if (attr==DEF_ZOK_FLOA) {
		if (scale >= 8) scale = 8;
		else scale = 4;
	}
/*
printf("_get_size_scale: name=[%s] attr=%d size=%d scale=%d scale0=%d\n",
name,attr,size,scale,scale0);
*/
	iParm[0] = scale0;
	iParm[1] = size;
	iParm[2] = scale;
	return 0;
}

/****************************************/
/*	felread1(fp,attr,size,scale)		*/
/****************************************/
static int _func_felread1(ppWork,nparm,pParm,ope,iParm,fp)
char **ppWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
FILE *fp;
{
	int iRc,ret,i,len,attr,size,scale0,scale,iVal,val[2],j,k,dec_size,len2;
	char *p1,*pWork,c,buf[256],*p2,dummy[128];
	short s,ws;
	double dVal;
	float  fVal;
	MPA    *ma;

	pWork = *ppWork;
	iRc = size = attr = scale = 0;

	if (iRc=cl_get_parm_bin(&pParm[0],&attr,"_func_felread1:attr:")) return -1;
	switch (attr) {
		case DEF_ZOK_CHAR: size = 1; break;
		case DEF_ZOK_BINA: size = sizeof(int); break;
		case DEF_ZOK_FLOA: size = sizeof(double); break;
		case DEF_ZOK_DECI: size = 15; break;
		case DEF_ZOK_BULK: size = 1; break;
		case DEF_ZOK_DATE: size = D_LEN_DATE; break;
		default:
			ERROROUT1(FORMAT(397),attr);	/* _func_felread1: 属性(%d)が不正です。 */
			return -1;
	}
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = 0;
	if (ret=_get_size_scale("_func_felread1",nparm-1,&pParm[1],iParm)) return ret;
	scale0 = iParm[0];
	size   = iParm[1];
	scale  = iParm[2];
	if (attr == DEF_ZOK_DECI) {
		dec_size = size;
		size = dec_size/2+1;
		len = size + sizeof(MPA);
		scale = scale0;
	}
	else if (attr == DEF_ZOK_DATE) len = size + sizeof(MPA);
	else len = size;
	if (!(p1=cl_tmp_const_malloc(len+1))) return ECL_MALLOC_ERROR;
	if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK || attr==DEF_ZOK_DECI) {
		*ppWork = pWork = p1;
		pWork[len] = '\0';
	}
	if (size > 0) {
		ret = fread(p1,1,size,fp);
		pGlobTable->err_no = errno;
/*
printf("_func_felread1: fread: ret=%d errno=%d\n",ret,errno);
*/
		if (k = ferror(fp)) ret = -1;
		else if (ret>0 && ret<size) {
			if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK || attr==DEF_ZOK_DATE) size = ret;
			else ret = -1;
		}
/*
printf("_func_felread1: ferror: k=%d errno=%d\n",k,errno);
*/
		if (ret <= 0) {
			if (ret)
				pGlobTable->exception = FILE_READ_EXCEPTION + pGlobTable->err_no;
			else {
				ret = ECL_END_OF_FILE;
				pGlobTable->exception = FILE_READ_END_EXCEPTION;
				ERROROUT("_func_felread1: end of file");
			}
			pGlobTable->error = ret;
			attr = DEF_ZOK_CHAR;
			size = 0;
			if (k) {
				ERROROUT2("_func_felread1: errno=%d %s",errno,strerror(errno));
			}
		}
		else if (ret > 0) {
			len = ret;
			if (attr == DEF_ZOK_DECI) len2 = 0;
			else len2 = size - scale;
			if (len2 > 0) {
				if (((attr==DEF_ZOK_BINA || attr==DEF_ZOK_FLOA) && scale0>=0) ||
				    ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK ||
				      attr==DEF_ZOK_DATE) && scale0<0)) {
					p2 = p1;
					p1 += len2;
				}
				else p2 = p1 + len2;
			/*
				if (attr == DEF_ZOK_CHAR) memset(p2,' ',len2);
				else if (attr == DEF_ZOK_BULK) memset(p2,0,len2);
			*/
			}
			switch (attr) {
			case DEF_ZOK_BINA:
				if (scale == 1) {
					i = *p1;
				}
				else if (scale == 2) {
					memcpy(&ws,p1,sizeof(short));
					s = ntohs(ws);
					i = s;
				}
				else {
					memcpy(val,p1,scale);
					if (scale == 8) val[0] = val[1];
					i = ntohl(val[0]);
				}
				memcpy(pWork,&i,sizeof(int));
				size = 4;
				break;
			case DEF_ZOK_FLOA:
				memcpy(val,p1,scale);
				if (scale == 4) {
					i = ntohl(val[0]);
					memcpy(&fVal,&i,sizeof(int));
					dVal = fVal;
					memcpy(pWork,&dVal,sizeof(double));
				}
				else {
					if (CLcommon.ucByteOrder) {
						i = ntohl(val[1]);
						memcpy(pWork,&i,sizeof(int));
						i = ntohl(val[0]);
						memcpy(pWork+sizeof(int),&i,sizeof(int));
					}
					else
						memcpy(pWork,val,sizeof(double));
				}
				size = 8;
				break;
			case DEF_ZOK_DECI:
				pWork = p1+size;
				if (ret = m_unpack((MPA *)pWork,p1,dec_size,scale)) {
					if (ret == MPA_ERR_INVALID)
						ERROROUT("_func_felread1: m_unpack: invalid number!!");
				/*	pGlobTable->exception = ret;	*/
					pGlobTable->exception = FILE_READ_EXCEPTION;
					pGlobTable->error = ret;
				}
				if (dec_size) {
					if ((ret=cl_mpa_scale(pWork,dec_size,scale)) < 0) return ret;
				}
			/*	size = sizeof(MPA);	*/
				*ppWork = pWork;
				break;
			case DEF_ZOK_DATE:
				ma = (MPA *)(p1+size);
				*ma = *m_get_i(1);
				memcpy(ma->num,p1,size);
				ma->exp = 6;
				ma->len = D_LEN_DATE;
				*ppWork = (char *)ma;
				size = sizeof(MPA);
				break;
			default:
				size = scale;
				*ppWork = p1;
			}
		}
		iRc = attr;
	}
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = scale;
	return iRc;
}

/****************************************/
/*	_felwrite1							*/
/****************************************/
static int _felwrite1(pInfoParm,size,scale,fp)
tdtInfoParm *pInfoParm;
int size,scale;
FILE *fp;
{
	int iRc,ret,i,retval,len,attr,iVal,val[2];
	char *p1,c,buf[256];
	uchar uc;
	short ws,s;
	double dVal;
	float  fVal;
	MPA mpa,*ma;

	attr = pInfoParm->pi_attr;
	p1   = pInfoParm->pi_data;
	len  = pInfoParm->pi_dlen;
	if (attr != DEF_ZOK_DECI) {
		if (scale <= 0) scale = len;
		else if (scale < len) len = scale;
	}
/*
printf("_felwrite1: size=%d scale=%d attr=%d len=%d\n",size,scale,attr,len);
*/
	switch (attr) {
		case DEF_ZOK_BINA:
		/*	memcpy(&iVal,p1,sizeof(int));	*/
			iVal = cl_get_data_long(pInfoParm);
/*
printf("_felwrite1: iVal=%d\n",iVal);
*/
			if (scale == 1) {
				c = iVal;
				p1 = &c;
			}
			else if (scale == 2) {
				ws = iVal;
				s = ntohs(ws);
				p1 = (char *)&s;
			}
			else if (scale == 4) {
				i = ntohl(iVal);
				p1 = (char *)&i;
/*
printf("_felwrite1: i=%08x\n",i);
*/
			}
			else {
				val[1] = ntohl(iVal);
				if (iVal >= 0) val[0] = 0;
				else val[0] = -1;
				p1 = (char *)val;
				len = 8;
			}
			break;
		case DEF_ZOK_FLOA:
			if (scale == 4) {
				memcpy(&dVal,p1,sizeof(double));
				fVal = dVal;
/*
printf("_felwrite1: fVal=%f\n",fVal);
*/
				memcpy(&i,&fVal,sizeof(int));
				val[0] = ntohl(i);
			}
			else {
				memcpy(&iVal,p1,sizeof(int));
				val[1] = ntohl(iVal);
				memcpy(&iVal,p1+sizeof(int),sizeof(int));
				val[0] = ntohl(iVal);
/*
printf("_felwrite1: val=%08x %08x\n",val[0],val[1]);
*/
			}
			p1 = (char *)val;
			break;
		case DEF_ZOK_DECI:
			if (size && scale>MIN_DEC_SCALE-1) {
				memcpy(&mpa,p1,sizeof(MPA));
				p1 = (char *)&mpa;
				if ((ret=cl_mpa_scale(p1,size,scale)) < 0) return ret;
			}
			len = m_pack_size(buf,size,p1);
			if (len == MPA_ERR_SIZE_OVER)
				ERROROUT1("_felwrite1: m_pack_size: size(%d) is few!!",size);
			p1 = buf;
			break;
		case DEF_ZOK_DATE:
			len = D_LEN_DATE;
			ma = (MPA *)p1;
			p1 = ma->num;
			break;
	/*
		case DEF_ZOK_CHAR:
		case DEF_ZOK_BULK:
	*/
	}
	if (len > 0) {
		if ((ret = fwrite(p1,len,1,fp)) <= 0) {
			len = -1;
			pGlobTable->err_no = errno;
		}
	}
	return len;
}

/****************************************/
/*	felwrite(fp,data1,data2,...)		*/
/****************************************/
static int _func_felwrite(pWork,nparm,pParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
FILE *fp;
{
	tdtInfoParm *pInfoParm;
	int iRc,ret,i,retval,len,attr,iVal,val[2],j,k;
	char *p1,c,buf[256];

	retval = 0;
	for (i=0;i<nparm;i++) {
		pInfoParm = &pParm[i];
		if (ret=cl_check_data_id(pInfoParm,0)) {
			ret += ECL_CHK_VAR_ERROR;
			break;
		}
		ret = _felwrite1(pInfoParm,0,0,fp);
		if (ret >= 0) {
			retval += ret;
			ret = 0;
		}
		else break;
	}
	if (ret < 0) {
	/*
		if (!(pGlobTable->exception = errno)) pGlobTable->exception = ret;
	*/
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		pGlobTable->error = ret;
		pGlobTable->err_no = errno;
		retval = ret;
		if (errno)
			ERROROUT2("_func_felwrite: errno=%d %s",errno,strerror(errno));
	}
	memcpy(pWork,&retval,sizeof(int));
	return 0;
}

/****************************************/
/*	felwrite1(fp,data,size,scale)		*/
/****************************************/
static int _func_felwrite1(pWork,nparm,pParm,ope,iParm,fp)
char *pWork;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
FILE *fp;
{
	tdtInfoParm *pInfoParm;
	int ret,retval,attr,len,size,scale,scale0,len2,mae_clear,len3,alen;
	char *p1,c,buf[256],*p2;

	retval = 0;
	pInfoParm = &pParm[0];
	if (ret=cl_check_data_id(pInfoParm,0)) return ret+ECL_CHK_VAR_ERROR;

	attr = pInfoParm->pi_attr;
	p1   = pInfoParm->pi_data;
	len  = pInfoParm->pi_dlen;
	iParm[0] = attr;
	if (attr !=DEF_ZOK_DECI) {
		iParm[1] = len;
		iParm[2] = 0;
	}
	else {
		iParm[1] = 0;
		iParm[2] = MIN_DEC_SCALE-1;
	}
	if (ret=_get_size_scale("_func_felwrite1",nparm-1,&pParm[1],iParm)) return ret;
	scale0 = iParm[0];
	size   = iParm[1];
	scale  = iParm[2];
	len3 = 0;
	if (attr == DEF_ZOK_DECI) {
		len2 = 0;
		scale = scale0;
	}
	else {
		len2 = size - scale;
		if (attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK) {
			if (scale > len) {
				len3 = scale - len;
				scale = len;
			}
		}
	}
	if (len2 > 0) {
		if (((attr==DEF_ZOK_BINA || attr==DEF_ZOK_FLOA) && scale0>=0) ||
		    ((attr==DEF_ZOK_CHAR || attr==DEF_ZOK_BULK ||
		      attr==DEF_ZOK_DATE) && scale0<0)) {
			mae_clear = 1;
		}
		else {
			mae_clear = -1;
		}
	}
	if ((alen=len2+len3) > 0) {
		p2 = buf;
		if (alen > sizeof(buf)) {
			if (!(p2=cl_tmp_const_malloc(alen))) return ECL_MALLOC_ERROR;
		}
		if (attr == DEF_ZOK_CHAR) memset(p2,' ',alen);
		else if (attr != DEF_ZOK_DECI) memset(p2,0,alen);
	}
	else mae_clear = 0;

	ret = 0;
	if (mae_clear > 0) {
		if ((ret = fwrite(p2,len2,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len2;

	}
	if (ret >= 0) {
		ret = _felwrite1(pInfoParm,size,scale,fp);
		if (ret >= 0) {
			retval += ret;
		}
	}
	if (ret>=0 && len3>0) {
		if ((ret = fwrite(p2,len3,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len3;
	}
	if (ret>=0 && mae_clear<0) {
		if ((ret = fwrite(p2,len2,1,fp)) <= 0) {
			ret = -1;
		}
		else retval += len2;
	}
	if (ret < 0) {
	/*
		if (!(pGlobTable->exception = errno)) pGlobTable->exception = ret;
	*/
		pGlobTable->exception = FILE_WRITE_EXCEPTION + errno;
		pGlobTable->error = ret;
		pGlobTable->err_no = errno;
		retval = ret;
		if (errno)
			ERROROUT2("_func_felwrite1: errno=%d %s",errno,strerror(errno));
	}
	else ret = 0;
	memcpy(pWork,&retval,sizeof(int));
	return ret;
}

/****************************************/
/*	readdir(dp)							*/
/****************************************/
static int _func_readdir(ppWork,iParm,dp)
char **ppWork;
int iParm[];
DIR *dp;
{
	struct dirent *dir;
	char *p1;
	int  len,ret;

	/*** ディレクトリのファイル名を取得する ***/
	dir = readdir(dp);
	if (dir) {
		/*
		 * if( dir->d_ino == 0 )
		 *     continue;
		 */
		p1  = dir->d_name;
		len = strlen(p1);
/*
printf("_func_readdir: file=[%s]\n",p1);
*/
		if (!(*ppWork = cl_tmp_const_malloc(len+1))) return ECL_MALLOC_ERROR;
		/* ファイル名のコピー */
		strcpy(*ppWork,p1);
	}
	else {
		*ppWork = "";
		if (errno) {
			ERROROUT2("_func_readdir: errno=%d %s",errno,strerror(errno));
			pGlobTable->exception = FILE_READ_EXCEPTION + errno;
			ret = -1;
		}
		else {
			pGlobTable->exception = FILE_READ_END_EXCEPTION;
			ret = ECL_END_OF_FILE;
			ERROROUT("_func_readdir: end of dir");
		}
		pGlobTable->error = ret;
	}
	return 0;
}

/****************************************/
/*										*/
/****************************************/
int func_file(ppWork,pOperator,nparm,pParm,ope,iParm)
char **ppWork;
char *pOperator;
tdtInfoParm *pParm;
int nparm,ope,iParm[];
{
	tdtInfoParm *pInfoParm;
	int iRc,ret,size,attr,scale;
	char *pWork;
	FILE *fp;
/*
printf("func_file: pOperator=%s nparm=%d ope=%d\n",pOperator,nparm,ope);
*/
	pGlobTable->error = 0;
	pWork = *ppWork;
	iRc = size = attr = scale = 0;
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = scale;
	if (ope==D_FUC_FOPEN || ope==D_FUC_POPEN ||	/* fopen, popen */
	    ope==D_FUC_OPENDIR ||	/* opendir */
	    ope==D_FUC_STAT    || 	/* stat */
	    ope==D_FUC_UNLINK) {	/* unlink */
		iRc =  _func_fopen(pWork,nparm,pParm,ope,iParm);
	}
	else {
		if (ope==D_FUC_FCLOSE    || ope==D_FUC_PCLOSE   ||
		    ope==D_FUC_CLOSEDIR  || ope==D_FUC_READDIR  ||
		    ope==D_FUC_FGETLINE  || ope==D_FUC_FPUTLINE ||
		    ope==D_FUC_FELREAD1  || ope==D_FUC_FELWRITE ||
		    ope==D_FUC_FELWRITE1 || ope==D_FUC_FPSTAT   ) {
			pInfoParm = &pParm[0];
			if (pInfoParm->pi_attr == DEF_ZOK_BINA)
				fp = (FILE *)cl_get_data_long(pInfoParm);
			else {
				/* ope=%d fpの属性が不正です。 */
				ERROROUT1(FORMAT(582),ope);
				return -1;
			}
			nparm--;
			pParm = &pParm[1];
		}
		else if (ope==D_FUC_GETLINE || ope==D_FUC_ELREAD1) fp = stdin;
		else if (ope==D_FUC_PUTLINE || ope==D_FUC_ELWRITE
		                            || ope==D_FUC_ELWRITE1) fp = stdout;
		else {
			ERROROUT1("func_file: operater=%d not defined!!",ope);
			return -1;
		}
		if (!fp) {
			ERROROUT1("ope=%d fp is NULL.",ope);
		/*	pGlobTable->exception = 	*/
			pGlobTable->exception = FILE_EXCEPTION;
			pGlobTable->error = ret = -1;
			memcpy(pWork,&ret,sizeof(int));
		}
		else {
			if (fp==stdin || fp==stdout || fp==stderr) ;
			else if (_check_fp('R',fp,NULL) <= 0) {
				/* ope=%d fpはclose済みです。 */
				ERROROUT1(FORMAT(583),ope);
				pGlobTable->exception = FILE_EXCEPTION;
				pGlobTable->error = ret = -1;
				memcpy(pWork,&ret,sizeof(int));
				return 0;
			}
			switch (ope) {
			case  D_FUC_FCLOSE:	/* fclose(fp) */
			case  D_FUC_PCLOSE:	/* pclose(fp) */
			case  D_FUC_CLOSEDIR:	/* closedir(dp) */
				iRc = _func_close(pWork,ope,fp);
				break;

			case D_FUC_FGETLINE:	/* fgetline(fp,size,opt) */
			case D_FUC_GETLINE:		/* getline(size,opt) */
				iRc = _func_fgetline(ppWork,nparm,pParm,ope,iParm,fp);
				break;

			case D_FUC_FPUTLINE:	/* fputline(fp,data1,data2,...) */
			case D_FUC_PUTLINE:		/* putline(data1,data2,...) */
				iRc = _func_fputline(pWork,nparm,pParm,ope,iParm,fp);
				break;

			case D_FUC_FELREAD1:	/* felread1(fp,attr,size,scale) */
			case D_FUC_ELREAD1:		/* elread1(attr,size,scale) */
				return _func_felread1(ppWork,nparm,pParm,ope,iParm,fp);

			case D_FUC_FELWRITE:	/* felwrite(fp,data1,data2,...) */
			case D_FUC_ELWRITE:		/* elwrite(data1,data2,...) */
				iRc = _func_felwrite(pWork,nparm,pParm,ope,iParm,fp);
				break;

			case D_FUC_FELWRITE1:	/* felwrite1(fp,data,size,scale) */
			case D_FUC_ELWRITE1:	/* elwrite1(data,size,scale) */
				iRc = _func_felwrite1(pWork,nparm,pParm,ope,iParm,fp);
				break;

			case D_FUC_READDIR:		/* readdir(dp) */
				iRc = _func_readdir(ppWork,iParm,(DIR *)fp);
				break;

			case D_FUC_FPSTAT:		/* fpstat(fp) */
				iRc = _func_fpstat(pWork,NULL,nparm,pParm,fp);
				break;

			default:
				ERROROUT1("func_file: operater=%d not defined!!",ope);
				iRc = -1;
			}
		}
	}
/*
	iParm[0] = attr;
	iParm[1] = size;
	iParm[2] = scale;
*/
#if 0
	if (!iRc && pGlobTable->try_level>0) {
		iRc = pGlobTable->error;
	}
#endif
	return iRc;
}

/****************************************/
/*										*/
/****************************************/
int cl_free_fp(hp)
HASHB *hp;
{
	long i,max;
	FILE *fp;
	int rc;
	char *p,*pn,*argv[2];
	struct stat tStat;

	hp->ha_key = (char *)argv;
	argv[0] = argv[1] = NULL;
	max = hp->ha_maxreg;
	for (i=1;i<=max;i++) {
		hp->ha_hix = i;
		if (akxshaslk(hp,&fp) > 0) {
			p = argv[1];
			if ((rc = fileno(fp)) >= 0) {
				rc = fstat(rc,&tStat);
			}
printf("i=%d rc=%d tStat.st_mode=%08x\n",i,rc,tStat.st_mode);
			if (rc < 0) {
						/* file/pipe/dir[%s]用のfpは無効です。 */
				if (p) ERROROUT1(FORMAT(584),p);
			}
			else {
				if (S_ISDIR(tStat.st_mode) || S_ISCHR(tStat.st_mode)) {
printf("closedir dp=%08x\n",fp);
					closedir((DIR *)fp);
					pn = "dir";
				}
				else if (S_ISFIFO(tStat.st_mode)) {
					pclose(fp);
					pn = "pipe";
				}
				else {
					fclose(fp);
					pn = "file";
				}
				pGlobTable->err_no = errno;
				if (p) ERROROUT2(FORMAT(398),pn,p);		/* %s[%s]をクローズしました。 */
			}
			if (p) Free(p);
		}
	}
	akxs_hasl_free(hp);
	return 0;
}
