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

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

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/un.h>
#include <unistd.h> /* fork(), execl(), read(), write(), close(), sleep(),
                       getpid(), getuid(), setgid(), setuid(), unlink(),  */
#include <strings.h> /* bzero() */
#include <string.h>
#include <memory.h>
#include <unistd.h>
#include <ctype.h>
#include <stdarg.h>
#include <pthread.h>
#include <time.h>
#include <pwd.h>
#include <fcntl.h>
#include <sys/msg.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>

#include "file_no.h"
#include "dir_path.h"
#include "file_lb.h"  /* 공통 Library Prototypes */
#include "type_def.h"
#if 0
#include <dirent.h>
#include "chg_struc.h"
#include "eps_ftp.h"
#else
#include "lb_func_list.h"
#endif
/*
 *========================================================================== 
 * 전역 변수 정의                                                            
 *==========================================================================
*/

#define  USE_TCP     "tcp"
#define  szSTR_BUF   7224
#define  szSTR_SND   1024

#define C_RETRY        3
#define SOCK_FAIL     -1
#define SOCK_SUCC      0
#define SOCK_FIN      -9

#define  TCP_MSGMAX  (1024 * 80)      /*-- 80 Kb : base on FEP Interface TFDTCycInfo --*/
#if 0
int HeaderSize = sizeof (_FTSHEAD) - TCP_MSGMAX;  /*-- size of socket message header --*/
#endif

/*
 *========================================================================
 *
 *   Function : lb_file2tbl()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : FILE을 TABLE로 변환 요청 처리
 *
 *========================================================================
*/

int   lb_file2tbl(chg_struc)
struct    chg_struc    *chg_struc;
{
    int    sock, len;

    chg_struc->tbl2file_div = 0;

    sock = lb_con_hnd_svr(PROC_OLTP);
    if (sock < 0)
    {
        lb_rehndlog(chg_struc);
        printf("socket connect fail222\n");
        return (1);
    }
    len = write(sock, chg_struc, sizeof(struct chg_struc));
    close(sock);
    if (len != sizeof(struct chg_struc)) {
             lb_rehndlog(chg_struc);
             return(2);
        }

    return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_file2tbl_bl()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : B/L 전용 FILE을 TABLE로 변환 요청 처리
 *
 *========================================================================
*/

int   lb_file2tbl_bl(chg_struc)
struct    chg_struc    *chg_struc;
{
    int    sock, len;

    chg_struc->tbl2file_div = 0;

    sock = lb_con_hnd_svr(PROC_BLOLTP);
    if (sock < 0)
    {
        lb_rehndlog(chg_struc);
        printf("socket connect fail222\n");
        return (1);
    }
    len = write(sock, chg_struc, sizeof(struct chg_struc));
    close(sock);
    if (len != sizeof(struct chg_struc)) {
             lb_rehndlog(chg_struc);
             return(2);
        }

    return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_tbl2file_bl()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : BL전용 TABLE을 FILE로 변환 요청 처리
 *
 *========================================================================
*/

int   lb_tbl2file_bl(chg_struc)
struct    chg_struc    *chg_struc;
{
    int    sock, len;

    chg_struc->tbl2file_div = 1;

    sock = lb_con_hnd_svr(PROC_BLOLTP);
    if (sock < 0)
    {
        lb_rehndlog(chg_struc);
        printf("socket connect fail111\n");
        return (1);
    }
    len = write(sock, chg_struc, sizeof(struct chg_struc));
    close(sock);
    if (len != sizeof(struct chg_struc)){
             lb_rehndlog(chg_struc);
             return(2);
        }
    return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_tbl2file()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : TABLE을 FILE로 변환 요청 처리
 *
 *========================================================================
*/

int   lb_tbl2file(chg_struc)
struct    chg_struc    *chg_struc;
{
    int    sock, len;

    chg_struc->tbl2file_div = 1;

    sock = lb_con_hnd_svr(PROC_OLTP);
    if (sock < 0)
    {
        lb_rehndlog(chg_struc);
        printf("socket connect fail112\n");
        return (1);
    }
    len = write(sock, chg_struc, sizeof(struct chg_struc));
    close(sock);
    if (len != sizeof(struct chg_struc)){
             lb_rehndlog(chg_struc);
             return(2);
        }
    return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_rehndlog()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 변환 요청 ERROR 시, REDO LOG-F에 저장
 *
 *========================================================================
*/

int   lb_rehndlog(chg_struc)
struct    chg_struc    *chg_struc;
{
    time_t    current_time;
    struct    tm    *struct_time;
    int    isfd, isrc;
    struct    write_info    wf;
#if 0
    if (chg_struc->file_id == FNO_SNDDATALIST)    /* JSMR은 Skip */
        return (0);
#endif
    current_time = time(0);
    struct_time    = local_time(&current_time);
    memset(&wf, 0, sizeof(struct write_info));
    sprintf((char *)wf.year, "%04d", struct_time->tm_year + 1900);
    sprintf((char *)wf.mon, "%02d", struct_time->tm_mon + 1);
    sprintf((char *)wf.day, "%02d", struct_time->tm_mday);
    sprintf((char *)wf.hr, "%02d", struct_time->tm_hour);

    isfd = lb_fopen(&wf, FNO_REHNDLOG, FOUTPUT+FC_MANULOCK);
    if (isfd == -ENOENT)
        isfd = lb_fbuild(&wf, FNO_REHNDLOG, FOUTPUT+FC_MANULOCK);
    if (isfd < 0)
        return (isfd);
    chg_struc->time = current_time;
    isrc = lb_writel(isfd, chg_struc , sizeof(struct  chg_struc));
    if (isrc < 0) isrc = -f_errno;
    lb_close(isfd);
    lb_cnt_redolog(1);
    return (isrc);
}

/*
 *========================================================================
 *
 *   Function : lb_call_svr_proc()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Call service program.
 *              지정 SVR PROCESS를 CALL, 처리 결과를 RETURN 받는다.
 *              비상주형 SVR 프로그램(송신자료작성 PROCESS) CALL시만 사용
 *========================================================================
*/

int   lb_call_svr_proc(svr_name, qwf)
char    *svr_name;
struct    write_info    *qwf;
{
    struct    write_info    *rwf;
    char     svr_path[128];
    int      pair_sock[2];
    int      pair_rsps[2];
    char     response_b[256];
    unsigned int response_l;
    int      send_l, recv_l;
    int      svr_pid;

    signal(SIGPIPE, SIG_IGN);
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair_sock) != 0)
    {
        qwf->return_code = -1;
        sprintf((char *)qwf->return_msg, "서버 프로그램을 CALL 할수 없습니다.");
        return (-1);
    }
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair_rsps) != 0)
    {
        close(pair_sock[0]);
        close(pair_sock[1]);
        qwf->return_code = -1;
        sprintf((char *)qwf->return_msg, "서버 프로그램을 CALL 할수 없습니다.");
        return (-1);
    }
        
    sprintf(svr_path, "%s/%s",  DIR_BIN, svr_name);
    signal(SIGCHLD, SIG_IGN);
    switch ((svr_pid = fork()))
    {
    case -1:
        close(pair_sock[0]);
        close(pair_sock[1]);
        close(pair_rsps[0]);
        close(pair_rsps[1]);
        qwf->return_code = -1;
        sprintf((char *)qwf->return_msg, "서버 프로그램을 CALL 할수 없습니다.");
        return (-1);
    case  0: /* child : svr process */
        dup2(pair_sock[1], 0);
        dup2(pair_rsps[1], 1);
        close(pair_sock[0]);
        close(pair_rsps[0]);
        execl(svr_path, svr_path, (char *)0);
        exit(0);
    default: /* parent: caller */
        close(pair_sock[1]);
        close(pair_rsps[1]);
        break;
    }
    send_l = write(pair_sock[0], qwf, sizeof(struct write_info));
    if (send_l != sizeof(struct write_info))
    {
        kill(svr_pid, SIGTERM);
        
        close(pair_sock[0]);
        close(pair_rsps[0]);
        qwf->return_code = -1;
        sprintf((char *)qwf->return_msg, "서버 프로그램을 CALL 할수 없습니다.");
        return (-1);
    }

    if (qwf->response == 0)
    {
        close(pair_sock[0]);
        close(pair_rsps[0]);
        return (0);
    }

    response_l = 0;
    for (;;)
    {
        send_l = sizeof(struct write_info) - response_l;
        recv_l = read(pair_rsps[0], &response_b[response_l], send_l);
        if (recv_l <= 0)
            break;
        response_l += recv_l;
        if (response_l >= sizeof(struct write_info))
            break;
    }
    close(pair_sock[0]);
    close(pair_rsps[0]);
    if (response_l >= sizeof(struct write_info))
    {
        
        rwf = (struct write_info *)response_b;
        qwf->return_code = rwf->return_code;
        memcpy(qwf->return_msg, rwf->return_msg, sizeof(qwf->return_msg));
        return (0);
    }
    if (kill(svr_pid, 0) >= 0)
        kill(svr_pid, SIGTERM);
    qwf->return_code = -1;
    sprintf((char *)qwf->return_msg, "서버 프로그램으로부터 응답이 없습니다.");
    return (-1);
}

/*
 *========================================================================
 *
 *   Function : lb_svr_snd()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Send request winfo to service program.
 *              지정 SVR PROCESS로 전문 전달 처리
 *              상주형 SVR 프로그램(상위통신 송신처리,...)으로 전달시 사용할 것.
 *========================================================================
*/

int   lb_svr_snd(svr_name, qwf)
char    *svr_name;
struct    write_info    *qwf;
{
    int    svr_sock;
    int    send_l;

    svr_sock = lb_con_hnd_svr(svr_name);
    if (svr_sock < 0)
        return (-1);

    send_l = write(svr_sock, qwf, sizeof(struct write_info));
    close(svr_sock);
    if (send_l != sizeof(struct write_info))
        return (-1);
    else
        return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_svr_sndm()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Send request winfo to service program.
 *              지정 SVR PROCESS로 전문 전달 처리
 *              상주형 SVR 프로그램(상위통신 송신처리,...)으로 전달시 사용할 것.
 *========================================================================
*/

int   lb_svr_sndm(svr_name, buff, len)
char    *svr_name;
char    *buff;
int    len;
{
    int    svr_sock;
    int    send_l;

    svr_sock = lb_con_hnd_svr(svr_name);
    if (svr_sock < 0)
        return (-1);

    send_l = write(svr_sock, buff, len);
    close(svr_sock);
    if (send_l != len)
        return (-1);
    else
        return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_con_hnd_svr()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 처리 SVR와 접속처리
 *
 *========================================================================
*/

int   lb_con_hnd_svr(svr_name)
char    *svr_name;
{
    struct    sockaddr_un    sock_svr;
    char    sock_path[128];
    int    sock;

    sprintf(sock_path, "%s/%s/%s", DIR_TCS, DIR_SPOOL, svr_name);
    sock = socket(AF_UNIX, SOCK_DGRAM, 0);        /* UDP */

    if (sock < 0) return (sock);
    bzero(&sock_svr, sizeof(sock_svr));
    strcpy(sock_svr.sun_path, sock_path);
    sock_svr.sun_family = AF_UNIX;

    if (connect(sock, (struct sockaddr *)&sock_svr, sizeof(sock_svr)) < 0)
    {
        perror("socket connect fail");
        printf("%s socket connect fail\n", sock_path);
        close(sock);
        return (-1);
    }

    return (sock);
}

/*
 *========================================================================
 *
 *   Function : lb_con_hnd_svr2()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 처리 SVR와 접속처리
 *
 *========================================================================
*/

int   lb_con_hnd_svr2(svr_name, lane_no)
char    *svr_name;
int    lane_no;
{
    struct    sockaddr_un    sock_svr;
    char    sock_path[128];
    int    sock;

    sprintf(sock_path, "%s/%s/%s%02d", DIR_TCS, DIR_SPOOL, svr_name, lane_no);
    sock = socket(AF_UNIX, SOCK_DGRAM, 0);        /* UDP */

    if (sock < 0) return (sock);
    bzero(&sock_svr, sizeof(sock_svr));
    strcpy(sock_svr.sun_path, sock_path);
    sock_svr.sun_family = AF_UNIX;

    if (connect(sock, (struct sockaddr *)&sock_svr, sizeof(sock_svr)) < 0)
    {
        perror("socket connect fail");
        printf("%s socket connect fail\n", sock_path);
        close(sock);
        return (-1);
    }

    return (sock);
}

/*
 *========================================================================
 *
 *   Function : lb_svr_sndt()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Send request winfo to service program.
 *              지정 SVR PROCESS로 전문 전달 처리
 *              상주형 SVR 프로그램(상위통신 송신처리,...)으로 전달시 사용할 것.
 *              연결형 Socket
 * 
 *========================================================================
*/

int   lb_svr_sndt(svr_name, buff, len)
char    *svr_name;
char    *buff;
int    len;
{
    int    svr_sock;
    int    send_l;

    svr_sock = lb_con_tcp_svr(svr_name);
    if (svr_sock < 0)
        return (-1);

    send_l = write(svr_sock, buff, len);

    close(svr_sock);
    if (send_l != len)
        return (-1);
    else
        return (0);
}

/*
 *========================================================================
 *
 *   Function : lb_con_tcp_svr()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : 처리 SVR와 접속처리
 * 
 *========================================================================
*/

int   lb_con_tcp_svr(svr_name)
char    *svr_name;
{
    struct    sockaddr_un    sock_svr;
    char    sock_path[128];
    int    sock;

    sprintf(sock_path, "%s/%s/%s", DIR_TCS, DIR_SPOOL, svr_name);
    sock = socket(AF_UNIX, SOCK_STREAM, 0);        /* TCP */
    if (sock < 0) return (sock);
    bzero(&sock_svr, sizeof(sock_svr));
    strcpy(sock_svr.sun_path, sock_path);
    sock_svr.sun_family = AF_UNIX;
    if (connect(sock, (struct sockaddr *)&sock_svr, sizeof(sock_svr)) < 0)
    {
        close(sock);
        return (-1);
    }

    return (sock);
}

/*
 *========================================================================
 *
 *   Function : lb_close_socket()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket close action.
 * 
 *========================================================================
*/

void lb_close_socket (sd)
int  sd;
{
  close (sd);
}

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

int  lb_tcp_con  (host_name, port_alias)
char *host_name;  /*-- /etc/hosts host Name --*/
char *port_alias; /*-- /etc/services Port Alias --*/
{
  struct sockaddr_in sin;
  struct servent *serv_ent;
  struct hostent *host_ent;
  int sd;

  /*-- setup connection - TCP --*/
  sd = socket (AF_INET, SOCK_STREAM, 0);
  if (sd < 0) lb_core_dump ("socket open fail.\n");

  /*-- get host name --*/
  host_ent = gethostbyname (host_name);
  if (host_ent == NULL) lb_error_exit ("gethostbyname :");

  /*-- get service port --*/
  serv_ent = getservbyname (port_alias, USE_TCP);
  if (serv_ent == NULL) lb_core_dump ("service open fail %s.\n", port_alias);

  memset ((char *)&sin, 0x00, sizeof (sin));
  sin.sin_family = AF_INET;
  bcopy (host_ent->h_addr, (char *) &sin.sin_addr, host_ent->h_length);
  sin.sin_port = serv_ent->s_port;

  if (connect (sd, (struct sockaddr *)&sin, sizeof (sin)) != 0)
  {
    lb_close_socket (sd);
    sd = -1;
    lb_debug_log_dump ("connect error. (%s:%s)\n", host_ent, port_alias);
  }

  return (sd);
}

/*
 *========================================================================
 *
 *   Function : lb_select_socket()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

int lb_select_socket( sockfd, sec, usec)
int sockfd;
int sec;
int usec;
{
    int        rc;
    int        m_errno = 0;
    struct     timeval    tv;
    fd_set     fdset;
    
    if (sockfd < 0) return -1;

    tv.tv_sec = sec;
    tv.tv_usec = usec;
    
    FD_ZERO (&fdset);
    FD_SET  (sockfd,&fdset);

    errno = 0;
    rc = select(sockfd+1,&fdset,(fd_set *)0,(fd_set *)0,&tv);
    m_errno = errno;
       if (rc > 0)
    {
        if (FD_ISSET(sockfd,&fdset)) return 1;
        else return -1;
    }
    else if ((rc < 0) && (m_errno == EINTR || m_errno == EAGAIN || 
    m_errno == ENOENT || m_errno == 0 || m_errno == EWOULDBLOCK)) return 0;
    else if (rc == 0) return 0;
    else return -1;
}

/*
 *========================================================================
 *
 *   Function : readn()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

int readn (sockfd, buff, len)
int sockfd;
char *buff;
int len;
{
    int        rc,n,left;
    int        m_errno = 0;
    int        cnt = 0;
    char    *ptr = 0x00;

    if (sockfd < 0) return -1;

    left = len;
    ptr  = buff;

    while (left > 0)
    {
        if (cnt == 10) break;
        errno = 0;
        n = read(sockfd,ptr,left);

        m_errno = errno;
        if (n > 0)
        {
            left -= n;
            ptr  += n;
            cnt = 0;
        }
        else if ((n < 0) && (m_errno == 0 || m_errno == EINTR || 
                            m_errno == EAGAIN || m_errno == EWOULDBLOCK)) 
        {
            if ((rc = lb_select_socket(sockfd,0,500000)) >= 0) 
            {
                cnt ++;
                continue;
            }
            else break;
        }
        else break;
    }
    return (len-left);
}

/*
 *========================================================================
 *
 *   Function : writen()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

int writen (sd, data, data_size)
int  sd;
void *data;
int  data_size;
{
  
  int  lret, snd_size;
  char    wbuf[TCP_MSGMAX];
  snd_size = data_size;
  memset (&wbuf, 0x00, sizeof (wbuf));
 
  /*-- 패킷 생성 시각 --*/

  memcpy (&wbuf, (char *)data, data_size);

  lret = write (sd, &wbuf, snd_size);
  if (lret != snd_size)
  {
    lb_debug_log_dump ("size writen Size=[%d] wish Size=[%d]\n", lret, snd_size);
    return (-1);
  }
  printf("SENDED DATA ======> size writen Size=[%d] wish Size=[%d]\n", lret, snd_size);
  return (lret);
}

/*
 *========================================================================
 *
 *   Function : lb_packet_dump()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

void lb_packet_dump (data, lsize, ldiv)
uchar *data;
int   lsize;
int   ldiv;  /*-- 캐리지 리턴할 갯수 (위치) --*/
{
  int k;

  for (k = 0; k < lsize; k ++)
  {
    if (MOD (k, ldiv) == 0) printf ("%02d(%03d)# ", k / ldiv, lsize);
    printf ("%c", *data ++);
  }
  printf ("\n");
}

/*
 *========================================================================
 *
 *   Function : lb_select()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

int lb_select(int sockfd,int sec,int usec)
{
    int       rc;
    int       m_errno = 0;
    struct    timeval    tv;
    fd_set    fdset;
    
    if (sockfd < 0) return -1;

    tv.tv_sec = sec;
    tv.tv_usec = usec;
    
    FD_ZERO (&fdset);
    FD_SET  (sockfd,&fdset);

    errno = 0;
    rc = select(sockfd+1,&fdset,(fd_set *)0,(fd_set *)0,&tv);
    m_errno = errno;
    if (rc > 0)
    {
        if (FD_ISSET(sockfd,&fdset)) return 1;
        else return -1;
    }
    else if ((rc < 0) && (m_errno == EINTR || m_errno == EAGAIN || 
              m_errno == ENOENT || m_errno == 0 || m_errno == EWOULDBLOCK)) return 0;
    else if (rc == 0) return 0;
    else return -1;
}

/*
 *========================================================================
 *
 *   Function : lb_tcp_snd()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : socket data read check
 * 
 *========================================================================
*/

int lb_tcp_snd (sd, data, data_size)
int  sd;
void *data;
int  data_size;
{
    int  lret, snd_size;

    snd_size = data_size;


    lret = write (sd, &data, snd_size);
    if (lret != snd_size)
    {
        lb_debug_log_dump ("size writen Size=[%d] wish Size=[%d]\n", lret, snd_size);
        return (-1);
    }

    return (lret);
}

/*
 *========================================================================
 *
 *   Function : lb_file_save()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : File Save (New File)
 * 
 *========================================================================
*/

int lb_file_save (file_Name, data, lsize)
char *file_Name;
void *data;
int   lsize;
{
    FILE *fd;
    fd = fopen (file_Name, "w");
    fwrite ((char *)data, lsize, 1, fd);
    fflush (fd);
    fclose (fd);

    return 0;
}

/*
 *========================================================================
 *
 *   Function : lb_file_size()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Get File Size
 * 
 *========================================================================
*/

int lb_file_size (File_Name)
char *File_Name;
{
    FILE  *fp;
    long   fsize;

    fp = fopen (File_Name, "r");
    if (fp == NULL) return (-1);
    (void) fseek (fp, 0L, SEEK_END);
    fsize = ftell (fp);
    fclose (fp);

    return ((int) fsize);
}

/*
 *========================================================================
 *
 *   Function : lb_file2shared()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   : Shared Memory Copy.
 * 
 *========================================================================
*/

int lb_file2shared (file_Name, shared, lsize)
char *file_Name;
void *shared;
int   lsize;
{

    FILE *fd;

    if (lsize != lb_file_size (file_Name)) return (-1);
    fd = fopen (file_Name, "r");
    fread ((char *)shared, lsize, 1, fd);
    fclose (fd);

    return (0);
}
#if 0
/*
 *========================================================================
 *
 *   Function : lb_snd_eps_file()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.05
 *   Modified :
 *   Remark   :
 * 
 *========================================================================
*/

int lb_snd_eps_file(_client_socket,file_name,dp) 
int _client_socket;
char *file_name;
struct	dirent *dp;
{
    _FTSHEAD fts;
    int ret;
    int file_name_size;
    int file_size;
    char read_buffer[TCP_MSGMAX];

    printf("Connect\n");

    memset(&read_buffer[0], 0x00, sizeof(read_buffer));
    memset(&fts,           0x00,sizeof(fts));

    file_name_size = strlen (dp->d_name);
    printf("Open File Full path : %s \n", file_name );

    file_size = lb_file_size (file_name);
    printf(" file_size : %d\n",file_size);

    /* 2)파일 이름을  보낸다. */
    memset (&fts, 0x00, sizeof (fts));
    memcpy (&fts.file_name[0], (char *)&dp->d_name, file_name_size);
    printf("fts.file_name =%s \n",fts.file_name);
    ret = writen (_client_socket, &fts, sizeof(fts));
    if (  ret < 0 )
    { 
        printf(" sendData : file_name send Fail = %d \n",ret);
        return -1;
    }

    /* 3) 파일 크기를 전송한다. */
    ret = writen (_client_socket, (void *)&file_size, sizeof(file_size));
    if (  ret < 0 )
    { 
        printf(" send_data : file_size send Fail = %d \n",ret);
        return -1;
    }

    lb_file2shared (file_name, &read_buffer, file_size);
    /* file_size 사용하기 때문에 다시 호스트 오더로 변경한다. */
    file_size = htonl(file_size);
    ret = writen (_client_socket, &read_buffer, file_size);

    if (  ret < 0 )
    { 
        printf(" send_data : File send Fail = %d \n",ret);
        return -1;
    }

    close(_client_socket);
    return 1;
}

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

int lb_rcv_eps_file (int _client_socket, _FTSHEAD *fts, char work_path[128])
{
    int file_size;
    char read_buffer [TCP_MSGMAX];
    char data_buf [TCP_MSGMAX];
    int ret;

    memset(&data_buf[0]   , 0x00, sizeof(data_buf));
    memset(&read_buffer[0], 0x00, sizeof(read_buffer));

    readn ( _client_socket, (char *)&fts, sizeof(_FTSHEAD));

    /* 그리고 fileSize 를 받는다. */
    readn ( _client_socket, (char *)&file_size, sizeof(file_size));

    /* 호스트 오더로 변경한다. */
    file_size = ntohl (file_size);

    /*fileSize가 0이면 종료한다. */
    printf ("file_size : %d\n",file_size);
    if ( file_size == 0)
    {
        printf (" File Size is 0 \n");
        return 0;
    }
    sprintf(read_buffer,"%s/%s", work_path, fts->file_name);
    printf("fopen -->read_buffer =%s\n",read_buffer);

    printf("recvFile : %s\n",read_buffer);
    memcpy(&fts->filesize[0], &file_size, sizeof(file_size));


    ret = readn ( _client_socket,data_buf,sizeof(data_buf));
    printf("ret = %d |  read_buffer =%s \n",ret,data_buf);

    /*파일명으로 파일을 연다. */
    lb_file_save (read_buffer, &data_buf,ret);
    memcpy(&fts->file_name[0], &read_buffer[0], sizeof(fts->file_name));

    return 1;
}
#endif