static    char    sccsid[]="%Z% %M% %I% %E% %U%";
/*************************************************
 *
 *	akxalog.c
 *
 *		  coded by A.Kobayashi 2010/04/04
 *
 *************************************************/
#include "akxcommon.h"

/********************************************/
/*                                          */
/********************************************/
int akx_get_log_time(char *buf, int len, char *format)
{
	static char *FORMAT;
	static int check=1;
	time_t  tw;
	struct  tm *str_tm;

	if (!buf) return -1;
	if (len <= 0) return -2;
	tw = time(NULL);
	str_tm = localtime(&tw);
	if (check) {
		strftime(buf,len,"%T",str_tm);
		if (*buf) FORMAT = "%Y/%m/%d %T";
		else FORMAT = "%Y/%m/%d %H:%M:%S";
		check = 0;
	}
	if (!format) format = FORMAT;
	return strftime(buf,len,format,str_tm);
}

/********************************************/
/*                                          */
/********************************************/
char *akx_log_time()
{
	static char buf[64];

	*buf = '\0';

	akx_get_log_time(buf,sizeof(buf),NULL);

	return buf;
}

/********************************************/
/*                                          */
/********************************************/
tdtLogCtlHead *akxa_log_new(int iMax)
{
	tdtLogCtlHead *tlh;
	tdtLogCtl     *tlc;
	int i;

	if (iMax <= 0) iMax = 10;
	if (!(tlh=(tdtLogCtlHead *)Malloc(sizeof(tdtLogCtlHead)))) return NULL;
	memset(tlh,0,sizeof(tdtLogCtlHead));
	tlh->log_max = iMax;
	tlh->rb_ct_w  = akxs_rb_new(0,0);
	if (!(tlc=(tdtLogCtl *)Malloc(sizeof(tdtLogCtl)*iMax))) {
		akxa_log_free(tlh);
		return NULL;
	}
	memset(tlc,0,sizeof(tdtLogCtl)*iMax);
	tlh->log_ctl = tlc;
	return tlh;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_free(
tdtLogCtlHead *tlh
)
{
	char *p;
	int i;
	tdtLogCtl *tlc,*tlc0;
	tdtRbCtl *pRb;

	if (tlh) {
		if (p=tlh->log_dir) Free(p);
		if (p=tlh->proc_name) Free(p);
		if (pRb=tlh->rb_ct_w) akxs_rb_all_free(pRb);
		if (tlc0 = tlh->log_ctl) {
			tlc = tlc0;
			for (i=0;i<tlh->log_max;i++,tlc++) {
				if (p=tlc->log_file) Free(p);
				if (p=tlc->log_file_path) Free(p);
				if (pRb=tlc->rb_file) akxs_rb_all_free(pRb);
				if (pRb=tlc->rb_srch) akxs_rb_all_free(pRb);
			}
			Free(tlc0);
		}
		Free(tlh);
	}
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
tdtLogCtl *akxa_log_get_ctl(
tdtLogCtlHead *tlh, 
int i)
{
	if (!tlh) return NULL;
	if (i<0 || i>=tlh->log_max) NULL;
	return &tlh->log_ctl[i];
}

/********************************************/
/*                                          */
/********************************************/
static int _compar(char *s,
tdtLogFileLine *tlFL
)
{
	char *p;
	int ret;

	if (!s || !tlFL) return -1;
	p = tlFL->lfl_file_name;
	if (!*p) return 0;
	return akxs_str_like(s,p);
}

/********************************************/
/*                                          */
/********************************************/
int akxa_rot_size(
tdtRotateCtl *rot, 
int n, long parm[])
{

	if (n > 0) {
		if (parm[0] >= 0) rot->rot_size_max = parm[0];
		else parm[0] = rot->rot_size_max;
	}
	if (n > 1) {
		if (parm[1] >= 0) rot->rot_file_max = parm[1];
		else parm[1] = rot->rot_file_max;
	}
#ifdef OLD_CHECK_POINT	/* 2001.11.2 Koba */
	if (n > 2) {
		if (parm[2] >= 0) rot->rot_check_point = parm[2];
		else parm[2] = rot->rot_check_point;
	}
#else
	if (n > 2) {
		if (parm[2] >= 0) rot->rot_option = parm[2];
		else parm[2] = rot->rot_option;
	}
	if (n > 3) {
		parm[3] = rot->rot_file_no;
	}
	if (n > 4) {
		parm[4] = rot->rot_check_point;
	}
#endif
	return rot->rot_size_max;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_size(
tdtLogCtlHead *tlh, 
int log_no, int n, long *parm)
{
	tdtLogCtl *tlc;

	if (!(tlc = akxa_log_get_ctl(tlh,log_no))) return -1;
	return akxa_rot_size(&tlc->log_rot,n,parm);
}

/********************************************/
/*                                          */
/********************************************/
char *akxa_rotate(
tdtRotateCtl *rot, 
char *fname)
{
	static char buf[256];
	char *p,*fn;
	int i,len,mt,opt,opt1,opt4,line;
	struct stat tStat;
	FILE *fp;

	opt = rot->rot_option;
	opt4 = opt & D_LOG_ROT_SIZE_LINE;
	if (opt4) rot->rot_count = 0;
	if (!fname || rot->rot_size_max <= 0) return fname;

	opt1 = opt & D_LOG_ROT_ROT_FILE;
	fn = fname;
	if (rot->rot_file_max > 0) {
		if ((len=strlen(fname)) >= sizeof(buf) - 12) return fn;
		memcpy(buf,fname,len+1);
		fn = buf;
		p = buf + len;
		if (!rot->rot_file_no) {	/* ファイルＮｏの初期値を求める */
			if (opt1) rot->rot_file_no = 1;
			else rot->rot_file_no = rot->rot_file_max + 1;
			rot->rot_size = mt = 0;
			for (i=1;i<=rot->rot_file_max;i++) {
				sprintf(p,"%d",i);
				if (stat(fn,&tStat)) break;
				if (tStat.st_mtime > mt) {
					mt = tStat.st_mtime;
					if (opt4) {
						if ((line = akxa_line_count(fn,0)) >= 0)
							rot->rot_size = line;
					}
					else rot->rot_size = tStat.st_size;
					rot->rot_file_no = i;
				}
			}
			if (opt4 && !opt1) {
				if ((line = akxa_line_count(fname,0)) >= 0) rot->rot_size = line;
			}
		}
		if (opt1) sprintf(p,"%d",rot->rot_file_no);
		else fn = fname;
	}

	if (opt4 || (++rot->rot_count >= rot->rot_check_point)) {
		if (opt4) {
			if (!(opt & D_LOG_ROT_NO_LINCR)) rot->rot_size++;
		}
		else {
			if (stat(fn,&tStat))
				rot->rot_size = 0;
			else
				rot->rot_size = tStat.st_size;
			rot->rot_count = 0;
			if (rot->rot_size > rot->rot_size_max)
				rot->rot_check_point--;
			else if (rot->rot_size < (rot->rot_size_max*9)/10)
				rot->rot_check_point++;
		}
		if (rot->rot_size >= rot->rot_size_max) {	/* ローテーション実行 */
			if (rot->rot_file_max > 0) {
									/* 次に退避するファイルＮｏを求める */
				if (++rot->rot_file_no > rot->rot_file_max) {
					rot->rot_file_no = 1;
				}
				fn = buf;
				sprintf(p,"%d",rot->rot_file_no);
				if (!opt1) {
				/*	unlink(fn);	*/
					rename(fname,fn);
					fn = fname;
				}
			}
			if (fp = fopen(fn,"w")) {
				if (!(opt & D_LOG_ROT_NO_HEAD))
					fprintf(fp,"***** Change Time (%s) *****\n",akx_log_time());
				fclose(fp);
			}
			rot->rot_size = 0;
			if (opt4) {
				rot->rot_count = 1;
				if (!(opt & D_LOG_ROT_NO_LINCR)) rot->rot_size++;
			}
		}
	}
	return fn;
}

/********************************************/
/*  ログフラグのチェック                    */
/********************************************/
int akxa_log_flag_check(
tdtLogCtl *tlc
)
{
	int f;

	if (tlc) f = tlc->log_flg &
	    (D_LOG_FLG_STDOUT|D_LOG_FLG_STDERR|D_LOG_FLG_FILE|D_LOG_FLG_SYSLOG);
	else f = 0;
	return f;
}

/********************************************/
/*  ログレベルとロググループのチェック      */
/********************************************/
int akxa_log_level_check(
tdtLogCtl *tlc, 
int group_level)
{
	int iLogLevel,group,level,iLogGrpMask,f;
	int i,chk_bit,lvl_mask;

	f = 0;
	if (tlc) {
		iLogLevel = tlc->log_level;
#if 0
		group = 1;
		if (iLogGrpMask=tlc->log_grp_mask) {
			if (group = level & iLogGrpMask) group &= iLogLevel;
			else group = 1;
		}
		lvl_mask = ~iLogGrpMask;
		level = group_level & lvl_mask;
		if (group && (iLogLevel & lvl_mask) >= level) f = 1;
#else
		level = group_level;
		if (iLogGrpMask=tlc->log_grp_mask) {
			lvl_mask = ~iLogGrpMask;
			group = level & iLogGrpMask;
			level &= lvl_mask;
			if (group) {
				if (group &= iLogLevel) {
/*
printf("akxa_log_level_check: group_level=%08x iLogGrpMask=%08x iLogLevel=%08x\n",group_level,iLogGrpMask,iLogLevel);
printf("akxa_log_level_check: group=%08x level=%d\n",group,level);
*/
					chk_bit = 0x40000000;
					for (i=1;i<=AKX_LOG_MAX_BITS-2;i++) {
						if (iLogGrpMask & chk_bit) {
							if ((group & chk_bit) && (tlc->log_lvll[i]>=level)) {
/*
printf("akxa_log_level_check: i=%d chk_bit=%08x lvll[i]=%d\n",i,chk_bit,tlc->log_lvll[i]);
*/
								f = 1;
								break;
							}
						}
						else break;
						chk_bit >>= 1;
					}
				}
			}
			else {
				if ((iLogLevel & lvl_mask) >= level) f = 1;
			}
		}
		else {
			if (iLogLevel >= level) f = 1;
		}
#endif
	}
	return f;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_out_check(tlc,level,file,line)
tdtLogCtl *tlc;
int  level,line;
char *file;
{
	tdtLogFileLine *tlFL;
	tdtRbCtl *pCt;
	int    iLogFlg,iLogLevel,line1,line2,disp,group;
	int    iLogGrpMask;

	/* ログフラグのチェック */
	if (!akxa_log_flag_check(tlc)) return 0;
	/* ログレベルとロググループのチェック */
#if 1
	if (!akxa_log_level_check(tlc,level)) return 0;
#else
	iLogLevel = tlc->log_level;
	group = 1;
	if (iLogGrpMask=tlc->log_grp_mask) {
		if (group = level & iLogGrpMask) group &= iLogLevel;
		else group = 1;
	}
	level &= ~iLogGrpMask;
	if (!group || (iLogLevel & ~iLogGrpMask) < level) return 0;
#endif
	/* ソースファイルの行数指定のチェック */
	if (line>0 && (pCt=tlc->rb_file)) {
		disp = 1;
		akxs_rb_read(pCt,0);
		while (tlFL=(tdtLogFileLine *)akxs_rb_read(pCt,1)) {
			if (!_compar(file,tlFL)) {
				disp = 0;
				line1 = tlFL->lfl_line[0];
				line2 = tlFL->lfl_line[1];
				if (line1<=0 && line2<=0) disp = 1;
				else {
					if (line1 > line2) line2 = line1;
					if (line>=line1 && line<=line2) disp = 1;
				}
				if (disp) break;
			}
		}
		if (!disp) return 0;
	}
	return 1;
}

/********************************************/
/*                                          */
/********************************************/
static char *_log_file_path(tlh,tlc,opt)
tdtLogCtlHead *tlh;
tdtLogCtl *tlc;
int opt;
{
	static char *cpPath2=NULL,*cpPath3=NULL;
	static char buf[256];
	char  *cpPath, *log_file, *p;
	int   len;

	if (!(cpPath = tlc->log_file_path)) {
		if (log_file = tlc->log_file) {
			p = akxt_add_dir2(tlh->log_dir,log_file,&cpPath2);
			if (!p) p = log_file;
			cpPath = akxt_add_dir2(tlh->cur_dir,p,&cpPath3);
			if (!cpPath) cpPath = p;
			tlc->log_file_path = Strdup(cpPath);
			cpPath = tlc->log_file_path;
		}
	}
	if ((opt & 0x01) && (tlc->log_rot.rot_option & D_LOG_ROT_ROT_FILE) &&
	     tlc->log_rot.rot_size_max>0 && cpPath) {
		if ((len=strlen(cpPath)) >= sizeof(buf) - 12) return NULL;
		memcpy(buf,cpPath,len);
		sprintf(buf+len,"%d",tlc->log_rot.rot_file_no);
		cpPath = buf;
	}
	return cpPath;
}

/********************************************/
/*                                          */
/********************************************/
char *akxa_log_file_path(tlh,log_no,opt)
tdtLogCtlHead *tlh;
int log_no,opt;
{
	tdtLogCtl *tlc;

	if (!(tlc = akxa_log_get_ctl(tlh,log_no))) return NULL;
	return _log_file_path(tlh,tlc,opt);
}

/********************************************/
/*                                          */
/********************************************/
static void _set_log_info
    (tlc,level,file,line,pri,format,a1,a2,a3,a4,a5)
tdtLogCtl *tlc;
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  level,line,pri;
{
	XHASHB *pha;
	int i;
	long key[2];
	tdtLogInfo qInfo,*pInfo;

	if (!(pha=tlc->log_info)) {
		if (!(pha = akxs_xhash_new2(sizeof(long)*2,50,0,sizeof(tdtLogInfo)))) return;
		tlc->log_info = pha;
	}
	key[0] = line;
	key[1] = (long)file;
	if (!(i = akxs_xhash2(pha,'r',key,NULL))) {
		qInfo.lgi_level = level;
		qInfo.lgi_line  = line;
		qInfo.lgi_pri   = pri;
		qInfo.lgi_file  = file;
		qInfo.lgi_format=format;
		qInfo.lgi_a1    = a1;
		qInfo.lgi_a2    = a2;
		qInfo.lgi_a3    = a3;
		qInfo.lgi_a4    = a4;
		qInfo.lgi_a5    = a5;
		i = akxs_xhash2(pha,'s',key,&qInfo);
	}
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_out_level_pri_main
    (tlh,log_no,level,file,line,pri,format,a1,a2,a3,a4,a5)
tdtLogCtlHead *tlh;
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  log_no,level,line,pri;
{
	tdtLogCtl *tlc;
	char   *cpPath=NULL, *cpProc, *log_file, *p;
	int    iLogFlg;

	if (!(tlc = akxa_log_get_ctl(tlh,log_no))) return -1;
	iLogFlg = tlc->log_flg;
	if (iLogFlg & D_LOG_FLG_OUT_INFO)
		_set_log_info(tlc,level,file,line,pri,format,a1,a2,a3,a4,a5);

	if (iLogFlg & D_LOG_FLG_CHK_PRI) level = pri;
	if (akxa_log_out_check(tlc,level,file,line) <= 0) return 0;

	/* ログ出力ファイル名の作成 */
	if (iLogFlg & D_LOG_FLG_FILE) {
		cpPath = _log_file_path(tlh,tlc,0);
		cpPath = akxa_rotate(&tlc->log_rot,cpPath);
	}
	cpProc  = tlh->proc_name;
	return akxa_log_out_pri(cpPath,iLogFlg,cpProc,file,line,pri,
	                     format,a1,a2,a3,a4,a5);
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_out_level_main(tlh,log_no,level,file,line,format,a1,a2,a3,a4,a5)
tdtLogCtlHead *tlh;
char *file,*format,*a1,*a2,*a3,*a4,*a5;
int  log_no,level,line;
{
	return akxa_log_out_level_pri_main
	       (tlh,log_no,level,file,line,0,format,a1,a2,a3,a4,a5);
}

/********************************************/
/*                                          */
/********************************************/
static int _pri2syspri(pri)
int pri;
{
	static struct {
		int priority;
		int syspri;
	} *ptbl,tbl[]=
		{AKX_LOG_EMERG  ,LOG_EMERG
		,AKX_LOG_ALERT  ,LOG_ALERT
		,AKX_LOG_CRIT   ,LOG_CRIT
		,AKX_LOG_ERR    ,LOG_ERR
		,AKX_LOG_WARNING,LOG_WARNING
		,AKX_LOG_NOTICE ,LOG_NOTICE
		,AKX_LOG_INFO   ,LOG_INFO
		,AKX_LOG_DEBUG  ,LOG_DEBUG
		,0 ,LOG_DEBUG+1};
	int i;

	ptbl = tbl;
	while (i=ptbl->priority) {
		if (pri >= i) {
			i = ptbl->syspri;
			break;
		}
		ptbl++;
	}
	if (!i) i = LOG_DEBUG+1;
	return i;
}

/********************************************/
/*                                          */
/********************************************/
static char *_priority(pri)
int pri;
{
	static struct {
		int priority;
		char *msg;
	} *ptbl,tbl[]=
		{LOG_EMERG  ,"EMERG"
		,LOG_ALERT  ,"ALERT"
		,LOG_CRIT   ,"CRIT"
		,LOG_ERR    ,"ERROR"
		,LOG_WARNING,"WARNING"
		,LOG_NOTICE ,"NOTICE"
		,LOG_INFO   ,"INFO"
		,LOG_DEBUG  ,"DEBUG"
		,0          ,NULL};
	char *p;

	ptbl = tbl;
	while (p=ptbl->msg) {
		if (pri == ptbl->priority) break;
		ptbl++;
	}
	if (!p) p = "null";
	return p;
}

/********************************************/
/*                                          */
/********************************************/
static void _new_line(fp,iLogFlg)
FILE *fp;
int iLogFlg;
{
/*
printf("_new_line: flg=%08x\n",iLogFlg);
*/
	akxa_log_new_line(fp,iLogFlg>>12);
}

/********************************************/
/*                                          */
/********************************************/
static int _log_chk_format_str(format,iParm,nParm)
char *format;
int iParm[],nParm;
{
	char *p,*pp,c;
	int i,len,ii,disp,ret,n,k;
/*
printf("_log_chk_format_str: format=[%s]\n",format);
*/
	mem_set_int(iParm,0,nParm+1);
	p = format;
	k = ret = ii = 0;
	disp = 0;
	len = strlen(format);
	while (len > 0) {
		n = akxqkanjilen2(p,len);
		if (n == 1) {
			c = *p;
			if (disp == 0) {
				if (c == '%') {
					ii++;
					disp = 1;
				}
			}
			else {
				if (c=='s') {
/*
printf("_log_chk_format_str: ii=%d\n",ii);
*/
					disp = 0;
					iParm[ii] = 1;
					ret++;
					if (ii >= nParm) break;
				}
				else if (c=='.' || (c>='0' && c<='9')) ;
				else disp = 0;
			}
		}
		else {
			k = 1;
			disp = 0;
		}
		p += n;
		len -= n;
	}
	iParm[0] = k;
	if (k) ret++;
/*
printf("_log_chk_format_str: ret=%d k=%d\n",ret,k);
*/
	return ret;
}

/********************************************/
/*                                          */
/********************************************/
static void _log_str_conv_free(nav,av0,av)
int nav;
char *av0[],*av[];
{
	int i;

	for (i=0;i<nav;i++) {
		if (av0[i] != av[i]) Free(av[i]);
	}
}

#define AKX_TMP_DIR	"/tmp"
/********************************************/
/*                                          */
/********************************************/
int akxa_log_out_pri(cpPath,iLogFlg,cpProc,file,line,pri,format,a1,a2,a3,a4,a5)
char *cpPath,*cpProc,*file,*format,*a1,*a2,*a3,*a4,*a5;
int  iLogFlg,line,pri;
{
	FILE *fp,*fo=NULL;
	char *buf,work[256],*p,*av0[6],*av[6];
	int  len, i, colon=0, syspri, opt, nParm, iParm[6], nStr, ret;
	struct stat tStat;
	static int error_count=0;
/*
printf("akxa_log_out_pri: cpPath=[%s] iLogFlg=%08x cpProc=[%s] file=[%s] file line=%d pri=%d\n format=[%s] file\n",
cpPath,iLogFlg,cpProc,file,line,pri,format);
*/
	if (!cpProc) cpProc = "";
	if (!file) file = "";

	if (iLogFlg & D_LOG_FLG_STDOUT) fo = stdout;
	if (iLogFlg & D_LOG_FLG_STDERR) fo = stderr;

	opt = iLogFlg>>16;
	nParm = 6;
	av0[0] = format;
	av0[1] = a1;
	av0[2] = a2;
	av0[3] = a3;
	av0[4] = a4;
	av0[5] = a5;
	nStr = _log_chk_format_str(format,iParm,nParm);

	syspri = _pri2syspri(pri);
	if (cpPath) {
		p = cpPath;
		fp = fopen(cpPath, "a");
		if (!fp) {
			len = strlen(cpPath);
			p = cpPath + len - 1;
			for (i=0;i<len;i++) {
				if (*p == '/') break;
				p--;
			}
			p++;
			sprintf(work,"%s/x_%s",AKX_TMP_DIR,p);
			fp = fopen(work, "a");
			p = work;
			if (!error_count && fp) {
				fprintf(fp,"*** open error file = [%s]\n",cpPath);
			}
			if (++error_count > 20) error_count = 0;
		}
		if (fp) {
			if (!(iLogFlg & D_LOG_FLG_NO_TIME)) {
				buf = akx_log_time();
				if (*buf){
					fprintf(fp,"%s ",buf);
				}
			}
			if (!(iLogFlg & D_LOG_FLG_NO_SRC)) {
				fprintf(fp, "%s/%s(%d)", cpProc, file, line);
				colon = 1;
			}
			else if (!(iLogFlg & D_LOG_FLG_NO_PROC)) {
				fprintf(fp, "%s", cpProc);
				colon = 1;
			}
			if (iLogFlg & D_LOG_FLG_PRIORITY) {
				fprintf(fp, "<%s>", _priority(syspri));
				colon = 1;
			}
			if (colon) fprintf(fp, ": ");
			if (format) {
				if (nStr) {
					ret = akxa_log_str_conv(iParm,nParm,av0,av,opt);
				}
				else mem_cpy_addr(av,av0,nParm);
				fprintf(fp,av[0],av[1],av[2],av[3],av[4],av[5]);
				if (nStr) _log_str_conv_free(nParm,av0,av);
			}
			_new_line(fp,iLogFlg);
			fclose(fp);
			if (!stat(p,&tStat)) {
				tStat.st_mode |= (S_IWGRP | S_IWOTH);
				chmod(p,tStat.st_mode);
			}
		}
	}
	if (fo) {
		if (*cpProc && !(iLogFlg & D_LOG_FLG_NO_PROC))
			fprintf(fo,"[%s] ", cpProc);
		else if (!(iLogFlg & D_LOG_FLG_NO_SRC))
			fprintf(fo,"%s(%d): ", file, line);
		if (format) {
			if (nStr && (opt & CD_OUTPUT_MASK)) {
				ret = akxa_log_str_conv(iParm,nParm,av0,av,opt);
			}
			else mem_cpy_addr(av,av0,nParm);
			fprintf(fo,av[0],av[1],av[2],av[3],av[4],av[5]);
			if (nStr) _log_str_conv_free(nParm,av0,av);
		}
		_new_line(fo,iLogFlg);
	}
	if ((iLogFlg & D_LOG_FLG_SYSLOG) &&
	    (strlen(cpProc)+strlen(file)+strlen(format)+15 < sizeof(work))) {
		if (!(iLogFlg & D_LOG_FLG_NO_SRC))
			sprintf(work,"%s/%s(%d): ", cpProc, file, line);
		else if (!(iLogFlg & D_LOG_FLG_NO_PROC))
			sprintf(work,"%s: ", cpProc);
		if (format) strcat(work,format);
		syslog(syspri,work,a1,a2,a3,a4,a5);
	}
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_str_conv(iParm,n,argv0,argv,opt)
char *argv0[],*argv[];
int iParm[],n,opt;
{
	char *p,*pp;
	int i,ret;

	ret = 0;
	for (i=0;i<n;i++) {
		argv[i] = argv0[i];
		if (iParm[i]) {
			if (p = argv0[i]) {
				ret = akxc_file_code_conv(&pp,p,strlen(p),1,opt);
				if (ret >= 0) argv[i] = pp;
/*
printf("akxa_log_str_conv: i=%d ret=%d argv0=[%s] argv0=[%s] \n",i,ret,argv0[i],argv0[i]);
*/
			}
		}
	}
	return ret;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_out(cpPath,iLogFlg,cpProc,file,line,format,a1,a2,a3,a4,a5)
char *cpPath,*cpProc,*file,*format,*a1,*a2,*a3,*a4,*a5;
int  iLogFlg,line;
{
	return akxa_log_out_pri(cpPath,iLogFlg,cpProc,file,line,0,
	                     format,a1,a2,a3,a4,a5);
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_flg(tlh,i,f)
tdtLogCtlHead *tlh;
int i,f;
{
	tdtLogCtl *tlc;

	if (!(tlc = akxa_log_get_ctl(tlh,i))) return -1;
	if (f >= 0) tlc->log_flg = f;

	return tlc->log_flg;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_set_proc_name(tlh,cpName)
tdtLogCtlHead *tlh;
char *cpName;
{
	int len;
	char *p;

	if (!tlh) return -1;
	p = tlh->proc_name;
	if (!cpName) {
		if (p) {
			Free(p);
			tlh->proc_name = NULL;
		}
		return 0;
	}
	len = strlen(cpName) + 1;
	if (p) {
		p=Realloc(p,len);
	}
	else {
		p=Malloc(len);
	}
	if (p) {
		strcpy(p,cpName);
		tlh->proc_name = p;
	}
	else return -2;
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
char *akxa_log_get_proc_name(tlh)
tdtLogCtlHead *tlh;
{
	if (!tlh) return NULL;
	return tlh->proc_name;
}

/********************************************/
/*                                          */
/********************************************/
static int _log_file_path_free(tlc)
tdtLogCtl *tlc;
{
	char *p;

	if (!tlc) return -1;
	if (p=tlc->log_file_path) {
		Free(p);
		tlc->log_file_path = NULL;
	}
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_file_path_free_all(tlh)
tdtLogCtlHead *tlh;
{
	int i;
	tdtLogCtl *tlc;

	if (!tlh) return -1;
	for (i=0;i<tlh->log_max;i++) {
		if (tlc = akxa_log_get_ctl(tlh,i)) _log_file_path_free(tlc);
	}
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
char *akxa_log_set_file_name(tlh, i, cpFile)
tdtLogCtlHead *tlh;
int  i;
char *cpFile;
{
	int len;
	char *p=NULL;
	tdtLogCtl *tlc;

	if (tlc = akxa_log_get_ctl(tlh,i)) {
		p = tlc->log_file;
		if (cpFile) {
			len = strlen(cpFile) + 1 + 8;
			if (p) {
				p = Realloc(p,len);
			}
			else {
				p = Malloc(len);
			}
			if (p) {
				strcpy(p,cpFile);
				tlc->log_file = p;
			}
			_log_file_path_free(tlc);
		}
	}

	return p;
}

/********************************************/
/*                                          */
/********************************************/
char *akxa_log_set_dir(tlh,cpDir)
tdtLogCtlHead *tlh;
char *cpDir;
{
	int len;
	char *p;

	if (!tlh) return NULL;
	p = tlh->log_dir;
	if (cpDir) {
		len = strlen(cpDir) + 1;
		if (p) {
			p = Realloc(p,len);
		}
		else {
			p = Malloc(len);
		}
		if (p) {
			strcpy(p,cpDir);
			tlh->log_dir = p;
		}
		akxa_log_file_path_free_all(tlh);
	}

	return p;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_group_level(tlh, log_no, flg, iLevel)
tdtLogCtlHead *tlh;
int log_no,flg,iLevel;
{
	tdtLogCtl *tlc;
	int level,group=0,i,chk_bit,grp_mask,lvl_mask;

	if (!(tlc = akxa_log_get_ctl(tlh,log_no))) return -1;
	if (flg) {
		grp_mask = tlc->log_grp_mask;
		lvl_mask = ~grp_mask;
		group = tlc->log_level & grp_mask;
		level = tlc->log_level & lvl_mask;
		if (flg & 0x02) group = iLevel & grp_mask;
		if (flg & 0x01) {
			level = iLevel & lvl_mask;
#if 1
			tlc->log_lvll[0] = level;
			chk_bit = 0x40000000;
			for (i=1;i<=AKX_LOG_MAX_BITS-2;i++) {
				if (grp_mask & chk_bit) {
					if (group & chk_bit) tlc->log_lvll[i] = level;
				}
				else break;
				chk_bit >>= 1;
			}
#endif
		}
/*
printf("akxa_log_group_level: log_no=%d group=%08x level=%d\n",log_no,group,level);
*/
		tlc->log_level = group | level;
	}
	return tlc->log_level;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_level(tlh, i,level)
tdtLogCtlHead *tlh;
int i,level;
{
	tdtLogCtl *tlc;
	int flg,ret;

	if (level < 0) flg = 0;
	else flg = 3;
	return  akxa_log_group_level(tlh, i, flg, level);
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_grp_mask(tlh, i, levelbitc)
tdtLogCtlHead *tlh;
int i, levelbitc;
{
	tdtLogCtl *tlc;

	if (!(tlc = akxa_log_get_ctl(tlh,i))) return -1;
	if (levelbitc>0 && levelbitc<AKX_LOG_MAX_BITS) {
		tlc->log_grp_mask = (0xffffffff << levelbitc) & 0x7fffffff;
	}
	else if (levelbitc == AKX_LOG_MAX_BITS) tlc->log_grp_mask = 0;

	return tlc->log_grp_mask;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_set_src_file(tlh,pCtChg,logno,ope,setno,file,line1,line2)
tdtLogCtlHead *tlh;
tdtRbCtl *pCtChg;
char *file;
int  logno,ope,setno,line1,line2;
{
	tdtLogCtl *tlc;
	tdtLogFileLine *tlFL;
	tdtRbCtl *pCt,*pCtW;
	char *p;
	int count=0,len,unmatch,no;
	char *buf;

	tlc = akxa_log_get_ctl(tlh,logno);
	if (!tlc) return -1;
	no = 0;
	if (ope < 0) {	/* del */
		if (!(pCt=tlc->rb_file)) return 0;
		while (tlFL=(tdtLogFileLine *)akxs_rb_get_n(pCt)) {
			no++;
			unmatch = 0;
			if (setno > 0) {
				if (no != setno) unmatch = 1;
			}
			else if (file) {
				if (*file) unmatch = strcmp(file,tlFL->lfl_file_name);
			}
			if (!unmatch) {
				count++;
				if (pCtChg) {
					tlFL->lfl_ope = ope;
					tlFL->lfl_no = no;
					akxs_rb_set_n(pCtChg,tlFL);
				}
				else Free(tlFL);
			}
			else
				akxs_rb_set_n(tlh->rb_ct_w,tlFL);
		}
		tlc->rb_file = tlh->rb_ct_w;
		tlh->rb_ct_w  = pCt;
	}
	else if (ope > 0) {	/* add or mod */
		pCt = tlc->rb_file;
		if (setno > 0) {
			if (pCt) {
				akxs_rb_read(pCt,0);
				while (tlFL=(tdtLogFileLine *)akxs_rb_read(pCt,1)) {
					no++;
					if (setno == no) {
						if (file && *file) {
							len = strlen(file);
							if (tlFL=(tdtLogFileLine *)Realloc(tlFL,
							                    sizeof(tdtLogFileLine)+len)) {
								strcpy(tlFL->lfl_file_name,file);
							}
							else return -4;
						}
						if (line1 > 0) tlFL->lfl_line[0] = line1;
						if (line2 > 0) tlFL->lfl_line[1] = line2;
						count++;
						if (pCtChg) {
							tlFL->lfl_ope = ope;
							tlFL->lfl_no = no;
							akxs_rb_set_n(pCtChg,tlFL);
						}
						break;
					}
				}
			}
		}
		else {
			if (file) {
				if (!*file) file = "%";
			}
			else file = "%";
			if (!pCt) {
				if (!(pCt=tlc->rb_file=akxs_rb_new(0,0))) return -2;
			}
			len = strlen(file);
			if (tlFL=(tdtLogFileLine *)Malloc(sizeof(tdtLogFileLine)+len)) {
				tlFL->lfl_line[0] = line1;
				tlFL->lfl_line[1] = line2;
				strcpy(tlFL->lfl_file_name,file);
				akxs_rb_set_n(pCt,tlFL);
				count++;
				if (pCtChg) {
					tlFL->lfl_ope = ope;
					tlFL->lfl_no = pCt->rb_used;
					akxs_rb_set_n(pCtChg,tlFL);
				}
			}
			else return -3;
		}
	}
	else {	/* ref */
		if (!(pCt=tlc->rb_file)) return 0;
		akxs_rb_read(pCt,0);
		while (tlFL=(tdtLogFileLine *)akxs_rb_read(pCt,1)) {
			no++;
			unmatch = 0;
			if (setno > 0) {
				if (no != setno) unmatch = 1;
			}
			else if (file) {
				if (*file) unmatch = strcmp(file,tlFL->lfl_file_name);
			}
			if (!unmatch) {
				count++;
				if (pCtChg) {
					tlFL->lfl_ope = ope;
					tlFL->lfl_no = no;
					akxs_rb_set_n(pCtChg,tlFL);
				}
				if (setno > 0) break;
			}
		}
	}
	return count;
}

/*********************************************/
/*  argv[0]:"srcfile"                        */
/*  argv[1]:logno                            */
/*  argv[2]:filename  / setno    > 0         */
/*  argv[3]:line1     / filename != null     */
/*  argv[4]:line2     / line1    > 0         */
/*  argv[5]:          / line2    > 0         */
/*********************************************/
int akxa_log_set_src_parm(argc,argv,lParm)
char *argv[];
int  argc;
long lParm[];
{
	char c,*file;
	int  logno,ope,line1,line2,setno,i;

	if (argc < 2) return -1;
	c = *argv[1];
	if (c<'0' || c>'9') return -2;
	ope = line1 = line2 = i = setno = 0;
	file = "";
	logno = atoi(argv[1]);
	if (argc >= 3) {
		file = argv[2];
		c = *file;
		if (c == '-') {
			ope = -1;
			file++;
		}
		else if (c == '+') {
			ope = 1;
			file++;
		}
		if ((c = *file)>='0' && c<='9') {
			setno = atoi(file);
			file = "";
			i++;
			if (argc >= i+3) file = argv[i+2];
		}
	}
	if (argc >= i+4) line1 = atoi(argv[i+3]);
	if (argc >= i+5) line2 = atoi(argv[i+4]);
/*
printf("akxa_log_set_src_parm:logno=%d ope=%d setno=%d file=[%s] line1=%d line2=%d\n",logno,setno,ope,file,line1,line2);
*/
	lParm[0] = (long)argv[0];
	lParm[1] = logno;
	lParm[2] = ope;
	lParm[3] = setno;
	lParm[4] = (long)file;
	lParm[5] = line1;
	lParm[6] = line2;
	return 0;
}

/*********************************************/
/*  argv[0]:"srcfile"                        */
/*  argv[1]:logno                            */
/*  argv[2]:filename  / setno    > 0         */
/*  argv[3]:line1     / filename != null     */
/*  argv[4]:line2     / line1    > 0         */
/*  argv[5]:          / line2    > 0         */
/*********************************************/
int akxa_log_src_file(tlh,pCtChg,argc,argv)
tdtLogCtlHead *tlh;
tdtRbCtl *pCtChg;
int  argc;
char *argv[];
{
	int  rc;
	long pa[7];

	rc = akxa_log_set_src_parm(argc,argv,pa);
	if (!rc)
		rc = akxa_log_set_src_file(tlh,pCtChg,pa[1],pa[2],pa[3],pa[4],pa[5],pa[6]);
	return rc;
}

#define AKX_LOG_PARM_MAX	8
/********************************************/
/*	argv[0]:logno	  =>iParm[i]:			*/
/*	argv[1]:flag	  =>iParm[i]:			*/
/*	argv[2]:level	  =>iParm[i]:			*/
/*	argv[3]:size max  =>iParm[i]:			*/
/*	argv[4]:file max  =>iParm[i]:			*/
/*	argv[5]:option	  =>iParm[i]:			*/
/*	argv[6]:file name =>iParm[i]:			*/
/*	argv[7]:priority-+	iParm[i]:file number*/
/*	argv[8]:N/A		 |	iParm[i]:check		*/
/*	argv[9]:N/A		 +=>iParm[i]:priority	*/
/*********************************************/
/*****************************************************
	argv!=NULLのときは、argv[i]を使う。
	argv==NULLのときは、iParm_i[i]を使う。
	argv!=NULL && argc_i<0 のときは、
		argv[i]=="." || "-" のとき、iParm_i[i]を使う。
*******************************************************/
int akxa_log_set_parm2(tlh,argc_i,argv,nParm,iParm_i)
tdtLogCtlHead *tlh;
int  argc_i,nParm;
long iParm_i[];
char *argv[];
{
	int  logno,i,l,iset,size_K,j,optw,opt4,argc;
	long w,ww,iParm[10];
	char *pi,*fn=NULL,c,**ppNS,c1;
/*
printf("akxa_log_set_parm2:Enter argc_i=%d argv=%08x nParm=%d iParm_i=%08x\n",argc_i,argv,nParm,iParm_i);
*/
	if ((argc=argc_i) < 0) argc = -argc;
	if (nParm > 10) nParm = 10;
	i = 0;
	if (iParm_i) for (;i<nParm;i++) iParm[i] = iParm_i[i];
	for (;i<10;i++) iParm[i] = -1;
	size_K = 1000;
	opt4 = 0;
	if (argc > AKX_LOG_PARM_MAX) argc = AKX_LOG_PARM_MAX;
	if (argv) {
		ppNS = &(tlh->log_ecnv);
		akxcecvn(ppNS,NULL,0,NULL);	/* new */
	/*	for (i=0;i<AKX_LOG_PARM_MAX;i++) iParm[i] = -1;	*/
		if (argc > AKX_LOG_PARM_MAX) argc = AKX_LOG_PARM_MAX;
		for (i=0;i<argc;i++) {
			pi = argv[i];
			c = *pi;
			c1 = *(pi+1);
			if ((c=='.' || c=='-') && !c1) {
				if (argc_i >= 0) iParm[i] = -1;
				continue;
			}
			if (i == 6) {	/* LOGFILE */
			/*	if (c && c!='-') {	*/
					if (!stricmp(pi,"null")) pi = "";
					fn = pi;
					iParm[6] = (long)pi;
			/*	}	*/
			}
			else if ((i==2 || i==7) && *ppNS) {	/* level, priority */
				if ((j=akxcecvn(ppNS,pi,strlen(pi),&w)) >= 0) {
					if (w >= 0) iParm[i] = w;
				}
			}
			else {
				if (!(j=akxcgcvn(pi,strlen(pi),&w))) {
					if (w >= 0) iParm[i] = w;
				}
				else if (i==3 && j>0 && w>=0) {	/* size max */
					c = akxcupper(*(pi+j-1));
					if (c=='K' || c=='M' || c=='B' || c=='L') {
						iParm[i] = w;
						if (c == 'K') size_K = 1000;
						else if (c == 'M') size_K = 1000000;
						else if (c == 'B') size_K = 1;
						else if (c == 'L') {
							size_K = 1;
							opt4 = D_LOG_ROT_SIZE_LINE;
						}
					}
				}
			}
		}
	}
	else {
		for (i=argc;i<AKX_LOG_PARM_MAX;i++) iParm[i] = -1;
		if (argc>6 && nParm>6) fn = (char *)iParm[6];
	}

	if ((logno = iParm[0]) >= 0) {
		iParm[1] = akxa_log_flg(tlh,logno,iParm[1]);	/* LOGFLG */
		iParm[2] = akxa_log_level(tlh,logno,iParm[2]);	/* LOGLEVEL */
/*
printf("akxa_log_set_parm2: flg=%04x level=%08x\n",iParm[1],iParm[2]);
*/
		if (iParm[3] > 0) {		/* size max */
			iParm[3] *= size_K;
		}
		if (iParm[4] > 0) {		/* file max */
			if (iParm[4] > 255) iParm[4] = 255;
		}
		optw = iParm[5];		/* option */
/*
printf("akxa_log_set_parm2: iParm[6]=%08x\n",iParm[6]);
*/
		iParm[6] = (long)akxa_log_set_file_name(tlh,logno,fn); /* LOGFILE */
/*
printf("akxa_log_set_parm2: iParm[6]=%s fn=%08x\n",iParm[6],fn);
*/
		if (fn && !iParm[6]) iParm[6] = -2;
		w = iParm[6];
		iParm[7] = akxa_log_priority(tlh,logno,iParm[7]);	/* LOGPRIORITY */
		ww = iParm[7];
		if (opt4) {
			if (optw >= 0) iParm[5] |= opt4;
			else iParm[5] = opt4;
		}
		akxa_log_size(tlh,logno,5,&iParm[3]);
		if (opt4 && optw<0) {
			iParm[3] = iParm[4] = iParm[5] = -1;
			akxa_log_size(tlh,logno,3,&iParm[3]);
		}
		iParm[8] = iParm[7];
		iParm[7] = iParm[6];
		iParm[6] = w;
		iParm[9] = ww;
	}
	if (iParm_i) for (i=0;i<nParm;i++) {
		iParm_i[i] = iParm[i];
/*
printf("akxa_log_set_parm2:Exit: iParm_i[%d]=%08x\n",i,iParm_i[i]);
*/
	}
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_set_parm(tlh,argc,argv,iParm)
tdtLogCtlHead *tlh;
int  argc,iParm[];
char *argv[];
{
	return akxa_log_set_parm2(tlh,argc,argv,AKX_LOG_PARM_MAX,iParm);
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_clear(tlh,log_no,option)
tdtLogCtlHead *tlh;
int  log_no,option;
{
	tdtLogCtl *tlc;
	char   *cpPath, *log_file, *p, buf[256], *fn;
	static char *cpPath2=NULL,*cpPath3=NULL;
	tdtRotateCtl *rot;
	int i,len;
/*
printf("akxa_log_clear:log_no=%d,option=0x%08x\n",log_no,option);
*/
	if (!(tlc = akxa_log_get_ctl(tlh,log_no))) return -1;
	rot = &tlc->log_rot;
	cpPath = _log_file_path(tlh,tlc,0);
/*
printf("akxa_log_clear: cpPath = [%s]\n",cpPath);
*/
	if (cpPath) {
		unlink(cpPath);
		if (rot->rot_file_max>0 && (len=strlen(cpPath))<sizeof(buf)-12) {
			memcpy(buf,cpPath,len+1);
			fn = buf;
			p = buf + len;
			for (i=1;i<=rot->rot_file_max;i++) {
				sprintf(p,"%d",i);
/*
printf("akxa_log_clear: fn = [%s]\n",fn);
*/
				unlink(fn);
			}
		}
	}
	rot->rot_file_no = 0;
	rot->rot_check_point = 0;

	return 0;
}

/************************************************/
/*												*/
/************************************************/
int akxa_line_count(file, opt)
char *file;
int	 opt;
{
	FILE *fp;
	int  c,line,i,c2;

	if (!file) return -1;
	if (!(fp=fopen(file,"r"))) return -2;
	line = i = 0;
	while ((c=getc(fp)) != EOF) {
		i = 0;
		if (c == '\n') line++;
		else if (c == '\r') {
			line++;
			if ((c2=getc(fp)) == EOF) break;
			else if (c2 != '\n') i = 1;
		}
		else i = 1;
	}
	fclose(fp);
/*
printf("akxa_line_count: file=[%s] opt=%d line=%d i=%d\n",file,opt,line,i);
*/
	return line+i;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_set_command_parm(tlh,nset,logno_set,opt_string,parm_string,iOption)
tdtLogCtlHead *tlh;
int  nset;
tdtGeneralData *logno_set;
char *opt_string,*parm_string;
int  iOption;
{
	char c2,*p;
	int  n,ret,i,is,log_no,log_flg;
	long iParm[10];
	char parm[256],*argv2[9],logno_ch[12],buf[128];
	tdtGeneralData *pset;

	if (!opt_string || !parm_string || !logno_set) return -1;

	for (is=0,pset=logno_set;is<nset;is++,pset++) {
		if (p=pset->gd_data) {
			if (!stricmp(opt_string,p)) break;
		}
	}
	if (is < nset) {
		ret = 0;
		log_no = pset->gd_id;	/* log_no */
		n = akxtgetargv2(parm_string,&argv2[1],7,parm,sizeof(parm),5);
		if (n > 0) {
			argv2[0] = logno_ch;
			if (is == 0) {
				for (i=1,pset=&logno_set[1];i<nset;i++,pset++) {
					sprintf(logno_ch,"%d",(int)pset->gd_id);
					akxa_log_set_parm2(tlh,n+1,argv2,0,NULL);
				}
				return 0;
			}
			else {
				sprintf(logno_ch,"%d",log_no);
				akxa_log_set_parm2(tlh,n+1,argv2,0,NULL);
			}
		}
		else if (n < 0) ret = n;
		else if ((log_flg=(int)pset->gd_resv) >= 0) {
			iParm[0] = log_no;
			iParm[1] = log_flg;
			akxa_log_set_parm2(tlh,2,NULL,2,iParm);
		}
	}
	else ret = -2;
	return ret;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_printf_len(buf,max_len,format,argc,argv)
char *buf,*format,*argv[];
int  max_len,argc;
{
	int  i,l,len,iper,width,w;
	char *p,c,*a,*b;

	if (p=format) {
		b = buf;
		i = len = iper = 0;
		while (c = *p++) {
			if (max_len>0 && len>=max_len) break;
			if (c == '\\') {
				if (b) *b++ = c;
				if (!(c = *p++)) break;
				if (b) *b++ = c;
				len += 2;
			}
			else if (c == '%') {
				if (i >= argc) break;
				if (argv) {
					iper  = 1;
					if (b) *b++ = c;
					len++;
				}
				width = atoi(p);
			}
			else if (iper) {
				a = argv[i];
				if (strchr("sdfecx",c)) {
					if (c == 's') {
						if (!a) {
							a = AKX_NULL_PRINT;
							argv[i] = a;
						}
						w = strlen(a);
					}
					else if (c == 'd') w = 11;
					else if (c == 'f') w = 18;
					else if (c == 'e') w = 14;
					else if (c == 'c') w = 1;
					else if (c == 'x') w = 8;
					if (width>0 && width>w) w = width;
					if (max_len>0 && len+w>=max_len) break;
					len += w;
				}
				else {
					if (b) *b++ = c;
					len++;
					continue;
				}
				if (b) *b++ = c;
				i++;
				iper = 0;
			}
			else {
				if (b) *b++ = c;
				len++;
			}
		}
		if (b) *b = '\0';
	}
	else len = -1;
	return len;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_group_priority(
tdtLogCtlHead *tlh,
int i,
int flg,
int iPriority)
{
	int group,priority;
	tdtLogCtl *tlc;

	if (tlc = akxa_log_get_ctl(tlh,i)) {
		if (flg) {
			group = tlc->log_priority & tlc->log_grp_mask;
			priority = tlc->log_priority & ~tlc->log_grp_mask;
/*
printf("akxa_log_group_priority:i=%d flg=%d cur_priority=%08x\n",
i,flg,tlc->log_priority);
*/
			if (flg & 0x02) group = iPriority & tlc->log_grp_mask;
			if (flg & 0x01) priority = iPriority & ~tlc->log_grp_mask;
			tlc->log_priority = group | priority;
		}
/*
printf("akxa_log_group_priority:i=%d flg=%d in_priority=%08x new_priority=%08x\n",
i,flg,iPriority,tlc->log_priority);
*/
		return tlc->log_priority;
	}
	else return -1;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_priority(
tdtLogCtlHead *tlh, 
int i, int priority)
{
	int ret,flg;
	tdtLogCtl *tlc;

	if (tlc = akxa_log_get_ctl(tlh,i)) {
		if (priority < 0) flg = 0;
		else flg = 3;

		if ((ret = akxa_log_group_priority(tlh, i, flg, priority)) < 0) return ret;
		return tlc->log_priority/* & ~tlc->log_grp_mask */;
	}
	else return -1;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_logfout(logfile,file,line,data,len)
char *logfile,*file,*data;
int  line,len;
{
	FILE *fp;
	int l,lp;
	char *p,buf[128];

	if (logfile) {
		if (!(fp = fopen(logfile,"a"))) return -1;
	}
	else fp = stdout;

	if (!file) file = "";
	p = akx_log_time();
	if (*p) fprintf(fp,"%s ",p);
	fprintf(fp, "%s(%d): ", file, line);
	l = len;
	p = data;
	while (l > 0) {
		memnzcpy(buf,p,l,sizeof(buf)-1);
		fprintf(fp, "%s", p);
		lp = strlen(p);
		if (lp < sizeof(buf)-1) break;
		p += lp;
		l -= lp;
	}
	fprintf(fp, "\n");
	if (fp != stdout) fclose(fp);
	return 0;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_new_line_str(char *s, int iFlg)
{
	int n;

	if (s) {
		n = 0;
		if (iFlg & AKX_NEWLINE_PUT_CR) {
			*s++ = '\r';
			n++;
		}
		if (!(iFlg & AKX_NEWLINE_NOT_LF)) {
			*s++ = '\n';
			n++;
		}
		*s = '\0';
	}
	else n = -1;
	return n;
}

/********************************************/
/*                                          */
/********************************************/
int akxa_log_new_line(FILE *fp, int iFlg)
{
	int n;
	char buf[3];

	if (fp) {
		n = akxa_log_new_line_str(buf,iFlg);
		if (n > 0) fwrite(buf,n,1,fp);
	}
	else n = -1;
	return n;
}
