/*
*========================================================================
*
*   SYSTEM   : AZN_PLAZA_LANE LIBRARY
*   FILE     : lb_file_ctrl.c
*   Progrmer : JBY (baarong@neighbor21.co.kr)
*   Date     : 2018.09.05
*   Modified :
*   Remark   :
 *              
 *========================================================================
*/

/*
 *========================================================================== 
 * Head  정의                                                            
 *==========================================================================
*/

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> 
#include "lb_func_list.h"
#include "def_set.h"
#include "file_nm.h"
#include "file_no.h"
#include "file_lb.h"
#include "path_def.h"

/*
 *========================================================================== 
 * 전역 변수 정의                                                            
 *==========================================================================
*/

#define    DEBUG__
#define    MAX_RETRY    7
#define    MAX_BUF_SIZE 60000

#define F_SUCC  0
#define F_FAIL -1
#define F_DUPL -100

extern int errno;

/*
 *========================================================================
 *
 *   Function : lb_file_exist_chk()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : FILE 존재 여부를 확인
 *
 *========================================================================
*/

int   lb_file_exist_chk(wf,file_no)
struct write_info *wf;
int file_no;
{
    struct  stat    statbuf;
    char            is_path[128];
    int             isrc;

    isrc = lb_fpath(wf, file_no, is_path);
    if(isrc < 0) return(isrc);

    return(stat(is_path,&statbuf)); 
}

/*
 *========================================================================
 *
 *   Function : lb_fopen()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : FILE을 OPEN 한다. LOCK관련 OPTION SETTTING
 *
 *========================================================================
*/

int   lb_fopen(wf, file_no, mode)
struct write_info *wf;
int file_no,mode;
{
    struct  stat    statbuf;
    char            is_path[128];
    int             isfd = -1;
    int             isrc,ii;
    int             ret;

    isrc = lb_fpath(wf, file_no, is_path);

    if(isrc < 0) return(isrc);

    ret = stat(is_path,&statbuf); 

    if(ret >= 0){
        for (ii = 0; ii < MAX_RETRY; ii++){
            isfd = lb_open(is_path, mode);
            if (isfd >= 0) break;
        }
    }

    if(isfd >= 0) return (isfd);
    else          return (-errno);    
}

int   lb_fbuild(wf, file_no, mode)
struct write_info *wf;
int file_no,mode;
{
    char    is_path[128];
    int     isfd, isrc;
    
    isrc = lb_fpath(wf, file_no, is_path);
    if (isrc < 0) return (isrc);

    isfd = lb_build(is_path, FINOUT+FC_EXCLLOCK);

    if (isfd == F_FAIL) return(-f_errno);

    lb_close(isfd);

    return (lb_fopen(wf, file_no, mode));
}

/*
 *========================================================================
 *
 *   Function : lb_fread()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_fread(isfd, file_no,record)
int isfd, file_no;
void *record;
{
    int    isrc;

    isrc = lb_readl(isfd, record, FNEXT , file_nm[file_no].rec_leng);
    if (isrc == F_FAIL){
        if(!f_errno) f_errno = 100;
        return (-f_errno);
    }
    
    return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : rcv_rgstr_tag_chrg()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_freadi(isfd,key,size,record,opt)
int isfd;
struct keydesc *key;
int size;
void *record;
int opt;
{
    int    i, cnt, isrc, ret = F_FAIL;
    char   buffer[MAX_BUF_SIZE];

    for(i=0;i<key->k_nparts;i++){
        for(cnt=0;cnt<key->k_part[i].kp_leng;cnt++){
        }
    }

    lseek(isfd,0,SEEK_SET);

    cnt = 0;
    switch(opt){
       case FEQUAL :
          while(ret == F_FAIL){
              isrc = lb_readl(isfd, buffer, FNEXT, size);

              if (isrc == F_FAIL) return(F_FAIL);
              cnt ++;
              for(i=0;i<key->k_nparts;i++){
                  if(!memcmp((char *)record+key->k_part[i].kp_start, 
                     &buffer[key->k_part[i].kp_start], key->k_part[i].kp_leng)){
                       ret = F_SUCC;
                  }else{
                      ret = F_FAIL; 
                      break;
                  }
              }
          }
          break;
       case FGREAT :
          while(ret == F_FAIL){
              isrc = lb_readl(isfd, buffer, FNEXT , size);

              if (isrc == F_FAIL) return(F_FAIL);
              cnt ++;
              for(i=0;i<key->k_nparts;i++){
                  if(memcmp((char *)record+key->k_part[i].kp_start,
                  &buffer[key->k_part[i].kp_start],key->k_part[i].kp_leng) < 0){
                       ret = F_SUCC; 
                       break;
                  }else ret = F_FAIL; 
              }
          }
          break;
       default : printf("L_ISREADI FUNC OPTION DON'T USED\n"); 
                 exit(0);
    }

    memcpy(record,buffer,size);
    f_recnum = cnt;

    return (size);
}

/*
 *========================================================================
 *
 *   Function : lb_freadx()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_freadx(wf,file_no,record,mode)
struct write_info *wf;
int file_no;
void *record;
int mode;
{
    int    isfd, isrc, iser;
//printf("freadx 1\n");
    isfd = lb_fopen(wf, file_no, FINPUT+FC_MANULOCK);
//printf("freadx 2[%d]\n", file_no);
    if (isfd < 0) return (isfd);
//printf("freadx 3[%d]\n", mode);
    if(mode == FEQUAL || mode == FGREAT){
//printf("freadx 4\n");
        isrc = lb_freadi(isfd,&file_nm[file_no].keys[0],file_nm[file_no].rec_leng,record,mode);
//printf("freadx 5\n");
        iser = isrc; 
        lb_close(isfd);
    }else{
        isrc = lb_readl(isfd, record, mode, file_nm[file_no].rec_leng);
        if (isrc < 0) iser = -f_errno;
        else          iser = isrc; 
        lb_close(isfd);
    }
//printf("freadx 6\n");
    return (iser);
}

/*
 *========================================================================
 *
 *   Function : lb_fwrite()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_fwrite(isfd,file_no,record,flag)
int isfd, file_no;
void *record;
int flag;
{
    int    isrc;
    int    ii;
    char   dummy[MAX_BUF_SIZE];


    memcpy(dummy,record,file_nm[file_no].rec_leng);

    ii = lb_start(isfd,&file_nm[file_no].keys[0],file_nm[file_no].rec_leng,dummy,FEQUAL); 
    if(ii == F_SUCCESS && !flag) return(F_DUPL);

    for (ii = 0; ii < MAX_RETRY; ii++)
    {
        isrc = lb_writeL(isfd, record, file_nm[file_no].rec_leng);
        if(f_errno == EINTR || f_errno == EDEADLK) continue;
        break;
    }

    if (isrc == F_FAIL) return (-f_errno);
    else                return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_fwritex()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_fwritex(wf,file_no,record,flag)
struct write_info *wf;
int file_no;
void *record;
int flag;
{
    int    isfd, isrc;
    int    ii;
    char   dummy[MAX_BUF_SIZE];


    memcpy(dummy,record,file_nm[file_no].rec_leng);

    isfd = lb_fopen(wf, file_no, FINOUT+FC_AUTOLOCK);
    if (isfd < 0) return (isfd);

    ii = lb_start(isfd,&file_nm[file_no].keys[0],file_nm[file_no].rec_leng,dummy,FEQUAL); 
    if(ii == F_SUCC && !flag) {
        lb_close(isfd);
        return(F_DUPL);
    }

    for (ii = 0; ii < MAX_RETRY; ii++)
    {
        isrc = lb_writeL(isfd, record, file_nm[file_no].rec_leng);
        if (f_errno == EINTR || f_errno == EDEADLK) continue;
        break;
    }

    lb_close(isfd);

    if (isrc == F_FAIL) return (-f_errno);
    else                return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_frewritex()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_frewritex(wf,file_no,record)
struct write_info *wf;
int file_no;
void *record;
{
    int    isfd, isrc;
    int    ii;
    char   dummy[MAX_BUF_SIZE];


    memcpy(dummy,record,file_nm[file_no].rec_leng);

    isfd = lb_fopen(wf, file_no, FINOUT+FC_AUTOLOCK);
    if (isfd < 0) return (isfd);

    ii = lb_start(isfd,&file_nm[file_no].keys[0],file_nm[file_no].rec_leng,dummy,FEQUAL); 

    for (ii = 0; ii < MAX_RETRY; ii++)
    {
        isrc = lb_writeL(isfd, record, file_nm[file_no].rec_leng);
        if (f_errno == EINTR || f_errno == EDEADLK) continue;
        break;
    }

    lb_close(isfd);

    if (isrc == F_FAIL) return (-f_errno);
    else                return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_frewcurr()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_frewcurr(isfd,file_no,record)
int isfd, file_no;
void *record;
{
    int    isrc;
    int    ii,size;

    size = file_nm[file_no].rec_leng;
    for (ii = 0; ii < MAX_RETRY; ii++)
    {
        lseek(isfd,-size,SEEK_CUR);
        isrc = lb_writeL(isfd, record , file_nm[file_no].rec_leng);
        if (isrc != 0 && (f_errno == EDEADLK || f_errno == EINTR)) continue;
        break;
    }
    if (isrc == F_FAIL) return (-f_errno);
    else                return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_frewrec()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_frewrec(isfd,file_no,key,record)
int isfd, file_no;
struct keydesc *key;
void *record;
{
    int    isrc;
    int    ii;

    for (ii = 0; ii < MAX_RETRY; ii++)
    {
        if((isrc = lb_fbrewrite(isfd, key, record, file_nm[file_no].rec_leng)) < 0) 
             f_errno = errno;
        else f_errno = 0;

        if (isrc == F_FAIL) continue;
        else                break;
    }

    if (isrc == F_FAIL) return (-f_errno);
    else                return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_fchk()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_fchk(wf, file_no, mode)
struct write_info *wf;
int file_no, mode;
{
    char    is_path[128];
    int    isfd,    isrc;

    isrc = lb_fpath(wf, file_no, is_path);
    if (isrc < 0)
        return (isrc);

    lb_get_right(RIGHT_SAM, 1);
    isfd = lb_fopen(wf, file_no, mode);
    lb_rel_right(RIGHT_SAM);

    if (isfd >= 0) return (isfd);
    if (isfd == -ENOENT) return (lb_fbuild(wf, file_no, mode));
    return (isfd);
}

/*
 *========================================================================
 *
 *   Function : lb_fpath()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int   lb_fpath(wf, file_no, path)
struct write_info *wf;
int file_no;
char *path;
{
    char    name[32];
    char    wrk_no[8];
    char    plz_id[2];
    int    year, mon, day;

    switch (file_nm[file_no].file_tail)
    {
    case TF_WRKR_NO: /* 근무자번호 */
        memcpy(wrk_no, wf->wrk_no, sizeof(wf->wrk_no));
        wrk_no[sizeof(wf->wrk_no)] = '\0';
        sprintf(name, "%s%s", file_nm[file_no].file_nm, wrk_no);
        break;
    case TF_DATE: /* 시간 */
        sprintf(name, "%s%.4s%.2s%.2s%.2s", file_nm[file_no].file_nm,
                   wf->year, wf->mon, wf->day, wf->hr);
        break;
    case TF_PLZ_WRKR_NO: /* 영업소 근무번호 */
        memset(plz_id, 0x0, sizeof(plz_id));
        memcpy(wrk_no, wf->wrk_no, sizeof(wf->wrk_no));
        memcpy(plz_id, wf->plz_id, 2);
        wrk_no[sizeof(wf->wrk_no)] = '\0';
        sprintf(name, "%s%.2s%.4s", file_nm[file_no].file_nm, plz_id, wrk_no);
        break;
    case TF_PLZ_NO:
        memset(plz_id, 0x0, sizeof(plz_id));
        memcpy(plz_id, wf->plz_id, 2);
        sprintf(name, "%s%.2s", file_nm[file_no].file_nm, plz_id);
        break;
    default:
        sprintf(name, "%s", file_nm[file_no].file_nm);
        break;
    }

    year = atoi((const char *)wf->year);
    mon = atoi((const char *)wf->mon);
    day = atoi((const char *)wf->day);
    if (year < 1000) year += 1900;

    switch (file_nm[file_no].dir_location)
    {
    case DF_BASE:
        sprintf(path, "%s/%s/%s", DIR_TCS, DIR_BASEINFO, name);
        break;
    case DF_DATA:
        sprintf(path, "%s/%s/%s", DIR_TCS, DIR_LANEDUMP, name);
        break;
    case DF_DATE:
        sprintf(path, "%s/%s/%04d%02d%02d/%s",DIR_TCS, DIR_LOG, year, mon, day, name);
        break;
    case DF_YEAR_MON:
        sprintf(path, "%s/%s/%04d%02d/%s", DIR_TCS, DIR_LOG, year, mon, name);
        break;
    case DF_YEAR:
        sprintf(path, "%s/%s/%04d/%s", DIR_TCS, DIR_LOG, year, name);
        break;
    case DF_REDO:
        sprintf(path, "%s/%s/%s", DIR_TCS, DIR_CONV, name);
        break;
    case DF_TMP:
        sprintf(path, "%s/%s/%s", DIR_TCS, DIR_TEMP, name);
        break;
    default:
        f_errno = ENOENT;
        return (-f_errno);
    }

    return (F_SUCC);
}

/*
 *========================================================================
 *
 *   Function : lb_read_trmn()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 단말수신 READ
 *
 *========================================================================
*/

int lb_read_trmn(isfd,trmn_r)
int isfd;
TRMNRCV *trmn_r;
{
    struct trmn_rcv    trmn_rcv;
    int    isrc,   isrn;

    trmn_r->leng = 0;
    for (isrn = 0;;isrn++)
    {
        isrc = read(isfd, &trmn_rcv, sizeof(struct trmn_rcv));
        if (isrc < 1)
        {
            if (isrn == 0) return (isrc);
            else           return (0);
        }
        memcpy(&trmn_r->data[trmn_r->leng], trmn_rcv.data, trmn_rcv.leng);
        trmn_r->leng += trmn_rcv.leng;
        if (trmn_rcv.flag == F_END) return (0);
    }
}

/*
 *========================================================================
 *
 *   Function : lb_read_passraw()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 통행원시 READ
 *
 *========================================================================
*/

int   lb_read_passraw(isfd, passraw_r)
int isfd;
PASSRAW *passraw_r;
{
    PASSRAW    passraw;
    int    isrc,   isrn;

    passraw_r->leng = 0;
    for (isrn = 0;;isrn++)
    {
        isrc = lb_readl(isfd, &passraw, FNEXT , 196);
        if (isrc != F_SUCCESS)
        {
            if (isrn == 0) return (isrc);
            else           return (F_SUCCESS);
        }
        memcpy(&passraw_r->data[passraw_r->leng], passraw.data, passraw.leng);
        passraw_r->leng += passraw.leng;
        if (passraw.flag == F_END) return (F_SUCCESS);
    }
}


/*
 *========================================================================
 *
 *   Function : lb_fbrewrite()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_fbrewrite(isfd, key, record, size)
int isfd;
struct keydesc *key;
void *record;
int size;
{
    int ret;
    char dummy[MAX_BUF_SIZE];
 
    memcpy(dummy,record,size);
    ret = lb_freadi(isfd,key,size,dummy,FEQUAL);
    if(ret == F_FAIL) return(F_FAIL);

    lseek(isfd,-size,SEEK_CUR);
    if(write(isfd,record,size) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_write()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_write(isfd, record, size)
int isfd;
void *record;
int size;
{
    if(write(isfd,record,size) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}


/*
 *========================================================================
 *
 *   Function : lb_writeL()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : char *fmt; //-- ex: "%s:%d:%x", "abc", 1, 20
 *
 *========================================================================
*/

int lb_writeL(isfd, record, size)
int isfd;
void *record;
int size;
{
    int len;

    if((len = write(isfd,record,size)) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(len);
    else         return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_writel()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_writel(isfd, record, size)
int isfd;
void *record;
int size;
{
    int len;

    lseek(isfd,0,SEEK_END);

    if((len = write(isfd,record,size)) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(len);
    else         return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_read()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_read(isfd, record, mode, size)
int isfd;
void *record;
int mode,size;
{
    return(lb_readl(isfd,record,mode,size));
}

/*
 *========================================================================
 *
 *   Function : lb_readfw()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_readfw(isfd, record, mode, size)
int isfd;
void *record;
int mode,size;
{
    int  mod;
    int  len;

#ifdef DEBUG_
printf("lb_readfw(paramter) isfd = %d size = %d\n",isfd,size);
#endif

    mod = mode & 0x0f;
    switch(mod){
       case FFIRST :  lseek(isfd,0,SEEK_SET); 
                       break; 
       case FLAST   :  lseek(isfd,-size,SEEK_END); 
                       break;
       case FNEXT   :  break;
       case FPREV   :  lseek(isfd,-size,SEEK_CUR); 
                       break;
       case FCURR   :  break;
    }

    if((len = read(isfd,record,size)) < 0) {
         f_errno = errno;
    } else f_errno = 0;

#ifdef DEBUG_
printf("lb_readfw(read) f_errno %d len %d\n",f_errno, len); 
#endif

    switch(mod){
       case FFIRST :  break; 
       case FLAST   :  break;
       case FNEXT   :  break;
       case FPREV   :  break;
       case FCURR   :  lseek(isfd,-size,SEEK_CUR);
                       break;
    }


    if(!f_errno && len == size) return(len);
    else                        return(F_FAIL);
}


/*
 *========================================================================
 *
 *   Function : lb_readl()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_readl(isfd, record, mode, size)
int isfd;
void *record;
int mode,size;
{
    int  mod;
    int  len;

#ifdef DEBUG_
printf("lb_readl(paramter) isfd = %d size = %d\n",isfd,size);
#endif

    mod = mode & 0x0f;
    switch(mod){
       case FFIRST :  lseek(isfd,0,SEEK_SET); 
                       break; 
       case FLAST   :  lseek(isfd,-size,SEEK_END); 
                       break;
       case FNEXT   :  break;
       case FPREV   :  lseek(isfd,-size,SEEK_CUR); 
                       break;
       case FCURR   :  break;
    }

    if((len = read(isfd,record,size)) < 0) {
         f_errno = errno;
    } else f_errno = 0;

#ifdef DEBUG_
printf("lb_readl(read) f_errno %d len %d\n",f_errno, len); 
#endif

    /* DELETE RECORED CHECK memcmp(record,dummy,size) */
    while(!f_errno && len == size && !lb_dummy_chk(record,size)){
        switch(mod){
       case FFIRST :  break;
           case FLAST   :  lseek(isfd,-(size*2),SEEK_CUR); 
                           break;
           case FNEXT  :  break;
           case FPREV  :  lseek(isfd,-(size*2),SEEK_CUR); 
                           break;
           case FCURR  :  break;
        }
        if((len = read(isfd,record,size)) < 0) f_errno = errno;
    else f_errno = 0;
    }

    switch(mod){
       case FFIRST :  break; 
       case FLAST  :  break;
       case FNEXT  :  break;
       case FPREV  :  break;
       case FCURR  :  lseek(isfd,-size,SEEK_CUR);
                       break;
    }

    if(!f_errno && len == size) return(len);
    else                        return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_dummy_chk()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 ***************************************************************************
*/

int lb_dummy_chk(dummy, size)
void *dummy;
int size;
{
    int i;
    for( i = 0; i < size ; i++){
          if(*((char *)dummy + i) !=  0x00) break;
    }
    
#ifdef DEBUG_
printf("lb_dummy_chk %d == %d\n",i,size);
#endif

    if(i == size) return(F_SUCC);
    else          return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_open()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_open(file_name, mod)
char *file_name;
int mod;
{
    int inout,lock,fd;

    /* READ & WRITE OPTION 처리 */
    inout = mod & 0x00ff;
    switch(inout){
        case FINPUT  : inout = O_RDONLY; break;
        case FOUTPUT : inout = O_WRONLY; break;
        case FINOUT  : inout = O_RDWR  ; break;
        default      : inout = O_RDWR  ; break;
    } 

    if((fd = open(file_name,inout)) < 0) f_errno = errno;
    else f_errno = 0;

    /* LOCK OPTION 처리 */
    lock = mod & 0xff00;
    switch(lock){
        case FC_EXCLLOCK  : if(lockf(fd,F_LOCK,0) < 0) f_errno = errno;
                           else f_errno = 0;

                           break;
        default          : break;
    } 

    if(!f_errno) return(fd);
    else{
         close(fd);
         return(F_FAIL);
    }
}


/*
 *========================================================================
 *
 *   Function : lb_build()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_build(file_name, mod)
char *file_name;
int mod;
{
    int inout,lock,fd;

    /* READ & WRITE OPTION 처리 */
    inout = mod & 0x00ff;
    switch(inout){
        case FINPUT  : inout = O_RDONLY; break;
        case FOUTPUT : inout = O_WRONLY; break;
        case FINOUT   : inout = O_RDWR  ; break;
        default       : inout = O_RDWR  ; break;
    } 

    unlink(file_name);
    if((fd = open(file_name,inout|O_CREAT,0666)) < 0) f_errno = errno;
    else f_errno = 0;
//    printf( "isbuild file open [%s]fd[%d]\n", file_name, fd );

    /* LOCK OPTION 처리 */
    lock = mod & 0xff00;
    switch(lock){
        case FC_EXCLLOCK  : if(lockf(fd,F_TLOCK,0) < 0) f_errno = errno;
                           else f_errno = 0;
                           break;
        default          : break;
    } 

    if(!f_errno) return(fd);
    else         {
       close(fd);
       return(F_FAIL);
    }

}

/*
 *========================================================================
 *
 *   Function : lb_erase()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_erase(file_name)
char *file_name;
{
    if(unlink(file_name) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_close()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_close(isfd)
int isfd;
{
    if(close(isfd) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}

/*
 *========================================================================
 *
 *   Function : lb_rename()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_rename(old_name, new_name)
char *old_name, *new_name;
{
    if(rename(old_name, new_name) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}


/*
 *========================================================================
 *
 *   Function : lb_start()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_start(isfd, key, size, record, mode)
int isfd;
struct keydesc *key;
int size;
void *record;
int mode;
{
    int ret;

    ret = lb_freadi(isfd,key,size,record,mode);
    if(ret == F_FAIL) return(F_FAIL);

    lseek(isfd,-size,SEEK_CUR);

    if(!errno) return(F_SUCC);
    else       return(-errno);
}

/*
 *========================================================================
 *
 *   Function : lb_record_cnt()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_record_cnt(isfd, fno)
int isfd, fno;
{
    struct stat buf;

    if(fstat(isfd,&buf)){
         f_errno = errno;
         return(F_FAIL);
    }

    return(buf.st_size/file_nm[fno].rec_leng);
}


/*
 *========================================================================
 *
 *   Function : lb_get_txpos()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_get_txpos(isfd, file_no, ldyb, pos)
int isfd, file_no, *pos;
char *ldyb;
{
    struct  stat buf;
    struct  keydesc *key;
    uchar   buffer[MAX_BUF_SIZE];
    int    ret=F_FAIL, i, isrc;
    int    size;
    int    first, mid = 0, last;

    if(fstat(isfd,&buf))
    {
        printf("fstat\n");
        f_errno = errno;
        return(F_FAIL);
    }

    size = file_nm[file_no].rec_leng;
    key = &file_nm[file_no].keys[0];

    if(buf.st_size < size)
    {
        printf("filesize fail\n");
        f_errno = errno;
        return(F_FAIL);
    }
    first=0;
    last = (buf.st_size / size);

    while(first<last)
    {
        mid=(first+last)/2;
        lseek(isfd, mid*size, SEEK_SET);
        isrc = read(isfd, buffer, size);
        if (isrc < size) return(F_FAIL);

        for(i=0;i<key->k_nparts;i++)
        {
            ret = memcmp( (char *)ldyb,
                &buffer[key->k_part[i].kp_start],
                key->k_part[i].kp_leng
                  );
            if(ret) break;
        }
        if(!ret) { *pos = mid;  return(buf.st_size / size - mid); }
        if(ret < 0) last=mid;
        else first=mid+1;
    }
    *pos = mid;
    return(buf.st_size / size - mid);
}

/*
 *========================================================================
 *
 *   Function : lb_get_xposint()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_get_xposint(isfd, file_no, ldyb, pos)
int isfd, file_no, *pos;
int *ldyb;
{
    struct   stat buf;
    struct   keydesc *key;
    uchar    buffer[MAX_BUF_SIZE];
    int    i, isrc;
    int    size;
    int    first,mid = 0, last;
    int    value = 0;

    if(fstat(isfd,&buf))
    {
        printf("fstat\n");
        f_errno = errno;
        return(F_FAIL);
    }

    size = file_nm[file_no].rec_leng;
    key = &file_nm[file_no].keys[0];

    if(buf.st_size < size)
    {
        printf("filesize fail\n");
        f_errno = errno;
        return(F_FAIL);
    }
    first=0;
    last = (buf.st_size / size);

    while(first<last)
    {
        mid=(first+last)/2;
        lseek(isfd, mid*size, SEEK_SET);
        isrc = read(isfd, buffer, size);
        if (isrc < size) return(F_FAIL);

        for(i=0;i<key->k_nparts;i++)
        {
            memcpy(&value,&buffer[key->k_part[i].kp_start], 4);;
            printf("%d :: %d  === n", value, *ldyb);
            if(value == *ldyb) break;
        }

        if(*ldyb==value)
        {
            *pos = mid;
            return(buf.st_size / size - mid);
        }
        if(*ldyb < value){ last=mid; printf("last=mid\n"); }
        else { first=mid+1; printf("first=mid\n");}
    }
    *pos = mid;
    return(buf.st_size / size - mid);
}

/*
 *========================================================================
 *
 *   Function : lb_delete()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 *
 *========================================================================
*/

int lb_delete(isfd, file_no, key, record)
int isfd, file_no;
struct keydesc *key;
void *record;
{
    int ret,size;
    char dummy[MAX_BUF_SIZE];

    size = file_nm[file_no].rec_leng;
    ret = lb_freadi(isfd,key,size,record,FEQUAL);
    if(ret == F_FAIL) return(F_FAIL);

    lseek(isfd,-size,SEEK_CUR);
    memset(dummy,0x00,size);
    if(write(isfd,dummy,size) < 0) f_errno = errno;
    else f_errno = 0;

    if(!f_errno) return(F_SUCC);
    else         return(F_FAIL);
}
