Embeded HTTPd daemon source reference 로서
pSOS가 탑재된 platform에서 다음의 command로 내부에 존재하는
HDD directory내용을 expoler에 표시하여 주는 기능을 수행한다.
----------------------------------------------------------------
Command
----------------------------------------------------------------

http://xxx.xxx.xxx.xxx:8088/Dir.do

임의의 lan port를 제공하는 embed platform에 Web server를 올려야 하는 경우
간단하게 사용할 수 잇다.

----------------------------------------------------------------
Main thread
----------------------------------------------------------------

/**
 * Function Name : JLW_Httpd_AcceptServer
 *
 * Function Description :
 * Input :  void *param
 * Output :
 * Return :
*/
void JLW_Httpd_AcceptServer(void *param)
{
 XONS_SOCKET   mainSock, childSock;
 XONS_SOCKADDR_IN  mainAddr, childAddr;
 int     opt = 1, addrLen;

 LogDebug("JLW_Httpd_AcceptServer() start port = %d", s_httpdServInfo.port);
 while (1)
 {
  if ((mainSock = XOAL_NS_Socket(XONS_AF_INET, XONS_SOCK_STREAM, XONS_IPPROTO_TCP)) == XONS_INVALID_SOCKET)
  {
   LogDebug("JLW_Httpd_AcceptServer() main socket open error");
   XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
   continue;
  }
  LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Socket open %d", mainSock);

  opt = 1;
  if (XOAL_NS_SetSockOpt(mainSock, XONS_SOL_SOCKET, XONS_SO_REUSEADDR, (char *)&opt, sizeof(int)) == XONS_SOCKET_ERROR)
  {
   LogDebug("JLW_Httpd_AcceptServer() main socket setsockopt error");
      XOAL_NS_CloseSocket(mainSock);
   XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
   continue;
    }
  LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_SetSockOpt OK");

  memset((char *)&mainAddr, '\0', sizeof(XONS_SOCKADDR_IN));
  mainAddr.sin_family      = XONS_AF_INET;
  mainAddr.sin_addr.s_addr = XONS_INADDR_ANY;
  mainAddr.sin_port        = XOAL_NS_htons(s_httpdServInfo.port);

  if (XOAL_NS_Bind(mainSock, (XONS_SOCKADDR *)&mainAddr, sizeof(mainAddr)) == XONS_SOCKET_ERROR)
  {
   LogDebug("JLW_Httpd_AcceptServer() main socket bind error");
      XOAL_NS_CloseSocket(mainSock);
   XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
   continue;
    }
  LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Bind OK");

  if (XOAL_NS_Listen(mainSock, 100) == XONS_SOCKET_ERROR)
  {
   LogDebug("Httpd_AcceptServer() main socket listen error");
      XOAL_NS_CloseSocket(mainSock);
   XOAL_MT_Sleep(HTTPD_SLEEP_TIME);
   continue;
    }
  LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Listen OK");

  while (1)
  {
   addrLen = sizeof(XONS_SOCKADDR_IN);
   memset((char *)&childAddr, '\0', addrLen);
   if ((childSock = XOAL_NS_Accept(mainSock, (struct sockaddr *)&childAddr, (int *)&addrLen)) == XONS_INVALID_SOCKET)
   {
    LogDebug("JLW_Httpd_AcceptServer() main socket accept error");
    break;
   }
   LogDebug("JLW_Httpd_AcceptServer() XOAL_NS_Accept %d", childSock);
   JLW_HttpdWork(childSock, &s_httpdServInfo);
      XOAL_NS_CloseSocket(childSock);
  }

     XOAL_NS_CloseSocket(mainSock);
 }
}

/**
 * Function Name : JLW_HttpdSendBasic
 *
 * Function Description :
 * Input :
      XONS_SOCKET sock
      JLW_WorkBuff *headBuff
      JLW_WorkBuff *BodyBuff
      int sendTimeout
 * Output :
 * Return :   int    : send result
*/
int JLW_HttpdSendBasic(XONS_SOCKET sock, JLW_WorkBuff *headBuff, JLW_WorkBuff *BodyBuff, int sendTimeout)
{
 int retVal;

 if ((retVal = JLW_Httpd_Send(sock, headBuff, sendTimeout)))
  return retVal;

 if (BodyBuff->len)
  return JLW_Httpd_Send(sock, BodyBuff, sendTimeout);
 else
  return retVal;
}

/**
 * Function Name : JLW_Httpd_Send
 *
 * Function Description :
 * Input :
      XONS_SOCKET sock
      strNetBuff *sendBuff
      int sendTimeout
 * Output :
 * Return :   int    : send result
*/
int JLW_Httpd_Send(XONS_SOCKET sock, JLW_WorkBuff *sendBuff, int sendTimeout)
{
 XONS_FDSET   writeFds, exceptFds;
 XONS_TIMEVAL  timeout;
 int     sendLen, posi, len;

// LogDebug("JLW_Httpd_Send() sendTimeout=%d", sendTimeout);

 posi = 0;
 sendLen = sendBuff->len;
 while (posi < sendLen)
 {
#ifdef __XOAL__SELECT__OK__
  if (sendTimeout > 0)
  {
   XOAL_NS_FD_ZERO(&writeFds);
   XOAL_NS_FD_ZERO(&exceptFds);
   XOAL_NS_FD_SET(sock, &writeFds);
   XOAL_NS_FD_SET(sock, &exceptFds);

   timeout.tv_sec  = sendTimeout / 1000;
   timeout.tv_usec = sendTimeout % 1000;
//   if (XOAL_NS_Select(sock + 1, NULL, &writeFds, &exceptFds, &timeout) <= 0 || XOAL_NS_FD_ISSET(sock, &exceptFds))
   if (XOAL_NS_Select(sock + 1, NULL, &writeFds, NULL, &timeout) <= 0)
   {
    LogDebug("JLW_Httpd_Send() XOAL_NS_Select writeFds error");
    return JLW_NET_SELECT_FAIL;
   }
  }
#endif

  if ((len = XOAL_NS_Send(sock, sendBuff->buff + posi, sendLen-posi, 0)) <= 0)
  {
   LogDebug("JLW_Httpd_Send() XOAL_NS_Send error %d", len);
   return JLW_NET_SEND_FAIL;
  }
  posi += len;
//  LogDebug("JLW_Httpd_Send() XOAL_NS_Send OK len=%d(%d/%d)", sendLen, posi, sendLen);
 }

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_Httpd_Recv
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     int receiveTimeout
 * Output :
     strNetBuff *recvBuff : return response data & length
     U32 *retContLen   : return Content-Length
 * Return :  int      : recv result
*/
int JLW_Httpd_Recv(XONS_SOCKET sock, JLW_WorkBuff *recvBuff, int receiveTimeout, U32 *retContLen)
{
 const char   contLenText[]   = "CONTENT-LENGTH:";

 XONS_FDSET  readFds, exceptFds;
 XONS_TIMEVAL timeout;
 int    sendLen, len, posi, rcvTotal, i, selectCnt, retVal;
 U32    contLen;
 U8    buffer[HTTPD_RECV_BUFF_SIZE+1], *retBuffer, *respHeader;
 char    *temp, *contLenPosi;

 memset((char *)recvBuff, '\0', sizeof(JLW_WorkBuff));
 contLen   = 0xFFFFFFFF;
 rcvTotal  = 0;
 retBuffer = NULL;
 temp      = NULL;
 memset(buffer, '\0', HTTPD_RECV_BUFF_SIZE+1);
 while (1)
 {
#ifdef __XOAL__SELECT__OK__
  if (receiveTimeout > 0)
  {
   XOAL_NS_FD_ZERO(&readFds);
   XOAL_NS_FD_ZERO(&exceptFds);
   XOAL_NS_FD_SET(sock, &readFds);
   XOAL_NS_FD_SET(sock, &exceptFds);

   timeout.tv_sec  = receiveTimeout / 1000;
   timeout.tv_usec = receiveTimeout % 1000;

#if 0
   if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, &exceptFds, &timeout)) <= 0
     || XOAL_NS_FD_ISSET(sock, &exceptFds))
#endif
   if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, NULL, &timeout)) <= 0)
   {
    LogDebug("JLW_Httpd_Recv() XOAL_NS_Select readFds error %d", selectCnt);
    break;
   }
  }
#endif

  if ((len = XOAL_NS_Recv(sock, buffer, HTTPD_RECV_BUFF_SIZE, 0)) <= 0)
   break;

  temp = (char *)retBuffer;
  if ((retBuffer = (U8 *)XOAL_Mem_Malloc(rcvTotal + len + 1)) == NULL)
  {
   LogDebug("JLW_Httpd_Recv() XOAL_Mem_Malloc error");
   if (temp)
    JLW_XOAL_Mem_Free(temp);
   return JLW_MEMORY_ALLOC_FAIL;
  }
  memset(retBuffer, '\0', rcvTotal + len + 1);

  if (temp)
  {
   memcpy(retBuffer, temp, rcvTotal);
   JLW_XOAL_Mem_Free(temp);
  }

  memcpy(retBuffer+rcvTotal, buffer, len);
  rcvTotal += len;
  memset(buffer, '\0', len);

  if (contLen == 0xFFFFFFFF)
  {
   if ((temp = strstr((char *)retBuffer, g_StrHeaderEnd)) == NULL)
    continue;

   len = temp - (char *)retBuffer;

   if ((respHeader = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
   {
    LogDebug("JLW_Httpd_Recv() XOAL_Mem_Malloc error");
    JLW_XOAL_Mem_Free(retBuffer);
    return JLW_MEMORY_ALLOC_FAIL;
   }
   memset(respHeader, '\0', len + 1);
   for (i = 0; i < len; i++)
    respHeader[i] = toupper(retBuffer[i]);

   if ((contLenPosi = strstr((char *)respHeader, contLenText)) == NULL)
   {
    JLW_XOAL_Mem_Free(respHeader);
    if (((temp - (char *)retBuffer) + 4) < rcvTotal)
    {
     LogDebug("JLW_Httpd_Recv() http status 400 error");
     JLW_XOAL_Mem_Free(retBuffer);

     return (JLW_NET_RESPONSE_ERROR_BASE+400);
    }
    break;
   }

   sscanf(contLenPosi + strlen(contLenText), "%lu", &contLen);
//   LogDebug("JLW_Httpd_Recv() Content-Length: OK len=%u", contLen);
   JLW_XOAL_Mem_Free(respHeader);
   if (retContLen)
    *retContLen = contLen;

   temp += strlen(g_StrHeaderEnd);
   len  =  rcvTotal - (temp - (char *)retBuffer);
   LogDebug("JLW_Httpd_Recv() len=%d", len);
   if (len >= contLen)
    break;

   if (contLen > HTTPD_NO_SAVE_CONTENT_LEN)
   {
    if ((retVal = JLW_HTTPD_RecvFile(sock, receiveTimeout, contLen,
       XOAL_F_GetDefaultDrive(), g_recvTempPath, g_recvTempFile, (U8 *)temp, len)))
    {
     JLW_XOAL_Mem_Free(retBuffer);
     return retVal;
    } else {
     *temp = '\0';
     break;
    }
   }
  } else {
   if ((temp = strstr((char *)retBuffer, g_StrHeaderEnd)) == NULL)
    continue;

   LogDebug("JLW_Httpd_Recv() len=%d", strlen(temp + strlen(g_StrHeaderEnd)));
   if (rcvTotal - ((temp + strlen(g_StrHeaderEnd)) - (char *)retBuffer) >= contLen)
    break;
  }
 }

 LogDebug("JLW_Httpd_Recv() XOAL_NS_Recv OK rcvTotal=%d", rcvTotal);
 recvBuff->len  = rcvTotal;
 recvBuff->buff = retBuffer;

 return JLW_WORK_OK;
}

----------------------------------------------------------------
Working functions
----------------------------------------------------------------

/**
 * Function Name : JLW_HttpdWork
 *
 * Function Description : http deamon work
 * Input :
 * Output :
      XONS_SOCKET sock
      JLW_HttpdServerInfo *servInfo
 * Return :
*/
void JLW_HttpdWork(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo)
{
 JLW_WorkBuff  recvBuff, urlBuff;
 int    httpWorkFlag, retVal;
 char   *posi, *next, *temp;
 U32    contLen;

 if ((retVal = JLW_Httpd_Recv(sock, &recvBuff, servInfo->recvTime, &contLen)))
 {
  LogDebug("JLW_HttpdWork() JLW_Httpd_Recv error");
  return;
 }
 JLW_HttpdConv2Char(recvBuff.buff);

// JLW_HTTPD_SendHttpdError(sock, servInfo, 200, "test");

 if ((httpWorkFlag = JLW_HttpMethodCheck((char *)recvBuff.buff, &next)) < 0)
 {
  LogDebug("JLW_HttpdWork() command read error");
  JLW_XOAL_Mem_Free(recvBuff.buff);
  return;
 }

 posi = next;
 if (JLW_HttpdGetWordAlloc(posi, ' ', TRUE, &urlBuff, &next))
 {
  LogDebug("JLW_HttpdWork() url read error");
  JLW_XOAL_Mem_Free(recvBuff.buff);
  return;
 }

 if ((posi = strchr((char *)urlBuff.buff, '?')))
  *posi = '\0';

 if (!(next = strrchr((char *)urlBuff.buff, '.')))
 {
  LogDebug("JLW_HttpdWork() work not found error");

  JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
  JLW_XOAL_Mem_Free(urlBuff.buff);
  JLW_XOAL_Mem_Free(recvBuff.buff);
  return;
 }

 if (!strcmp(next, ".do"))
 { /* CGI WORK */
  if (JLW_HTTPD_CGIWork(sock, servInfo, &recvBuff, httpWorkFlag, &urlBuff, posi, contLen))
  {
   if (posi)
    *posi = '&';
   JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
  }
 } else {
  char pathName[HTTPD_SMALL_BUFF_SIZE*2+1], fileName[HTTPD_SMALL_BUFF_SIZE+1];
  int  len;

  memset(fileName, '\0', sizeof(fileName));
  memset(pathName, '\0', sizeof(pathName));
  strcpy(pathName, g_httpBasePath);

  if ((temp = strrchr((char *)urlBuff.buff, '/')))
  {
   if ((next = strrchr((char *)urlBuff.buff, '\\')))
    if (temp < next)
     temp = next;
   strcpy(fileName, temp + 1);
  } else if ((temp = strrchr((char *)urlBuff.buff, '\\'))) {
   strcpy(fileName, temp + 1);
  } else {
   strcpy(fileName, (char *)urlBuff.buff);
  }

  if (temp)
  {
   if (urlBuff.buff[0] != '/' && urlBuff.buff[0] != '\\')
    strcat(pathName, "\\");

   memcpy(pathName + strlen(pathName), urlBuff.buff, temp - (char *)urlBuff.buff);
  }

  if (posi)
   *posi = '&';

  if (JLW_HTTPD_SendFile(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, fileName))
   JLW_HTTPD_SendHttpdError(sock, servInfo, 404, (char *)urlBuff.buff);
 }

 JLW_XOAL_Mem_Free(urlBuff.buff);
 JLW_XOAL_Mem_Free(recvBuff.buff);
}

/**
 * Function Name : JJLW_HttpMethodCheck
 *
 * Function Description : http command 를 얻는다.
 * Input :
 * Output :
      char *buffer
      char **next
 * Return :   int
*/
int JLW_HttpMethodCheck(char *buffer, char **next)
{
 char  command[HTTPD_COMMAND_LEN+1];
 int  retVal;

 if ((retVal = JLW_HttpdGetWordBuff(buffer, ' ', FALSE, command, HTTPD_COMMAND_LEN+1, next)))
  return retVal;

 if (!strcmp(command, "GET"))
  return HTTPD_COMMAND_GET;
 if (!strcmp(command, "POST"))
  return HTTPD_COMMAND_POST;

 return JLW_WORK_FAIL;
}

/**
 * Function Name : JLW_HttpdGetWordBuff
 *
 * Function Description : http command를 구한다.
 * Input :
 * Output :
      char *buffer
      char comp
      bool checkCrLf
      char *word
      int maxLen
      char **next
 * Return :   int    : find result
*/
int JLW_HttpdGetWordBuff(char *buffer, char comp, bool checkCrLf, char *word, int maxLen, char **next)
{
 char *posi, *prev, *quotation, *quotPrev;
 int  len;

 memset(word, '\0', maxLen);
 prev = buffer;
 while (1)
 {
  if ((posi = strchr(prev, comp)) == NULL)
  {
   if (checkCrLf && ((posi = strstr(buffer, g_StrCrLf)) == NULL))
    return JLW_WORK_FAIL;
  }

  quotPrev = prev;
  while ((quotation = strchr(quotPrev, '\"')) || (quotation = strchr(quotPrev, '\'')))
  {
   if (quotation && (posi > quotation))
   {
    if ((quotPrev = strchr(quotation+1, *quotation)))
    {
     if (posi < quotPrev)
      break;
     else {
      quotPrev++;
      continue;
     }
    } else
     return JLW_WORK_FAIL;
   }
   break;
  }
  if (posi < quotPrev)
  {
   prev = quotPrev+1;
   continue;
  }

  break;
 }

 len = posi - buffer;
 if (len >= maxLen)
  return JLW_BUFFER_OVERFLOW;

 memcpy(word, buffer, len);

 *next = posi + 1;

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_HttpdGetWordAlloc
 *
 * Function Description :
 * Input :
 * Output :
      char *buffer
      char comp
      bool checkCrLf
      JLW_WorkBuff *wordBuff
      char **next
 * Return :   int    : find result
*/
int JLW_HttpdGetWordAlloc(char *buffer, char comp, bool checkCrLf, JLW_WorkBuff *wordBuff, char **next)
{
 char *posi, *prev, *quotation, *quotPrev;
 int  len;

 memset((char *)wordBuff, '\0', sizeof(JLW_WorkBuff));
 prev = buffer;
 while (1)
 {
  if ((posi = strchr(prev, comp)) == NULL)
  {
   if (checkCrLf && ((posi = strstr(buffer, g_StrCrLf)) == NULL))
    return JLW_WORK_FAIL;
  }

  quotPrev = prev;
  while ((quotation = strchr(quotPrev, '\"')) || (quotation = strchr(quotPrev, '\'')))
  {
   if (quotation && (posi > quotation))
   {
    if ((quotPrev = strchr(quotation+1, *quotation)))
    {
     if (posi < quotPrev)
      break;
     else {
      quotPrev++;
      continue;
     }
    } else
     return JLW_WORK_FAIL;
   }
   break;
  }
  if (posi < quotPrev)
  {
   prev = quotPrev+1;
   continue;
  }

  break;
 }

 len = posi - buffer;
 if ((wordBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
 {
  LogDebug("JLW_HttpdGetWordAlloc() XOAL_Mem_Malloc fail");
  return JLW_MEMORY_ALLOC_FAIL;
 }
 memset(wordBuff->buff, '\0', len+1);
 wordBuff->len = len;

 memcpy((U8 *)wordBuff->buff, buffer, len);

 *next = posi + 1;

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_HttpdFindHeaderField
 *
 * Function Description :
 * Input :
 * Output :
      U8 *request
      char *field
 * Return :   U8 *  : 할당받은 data field
*/
U8 *JLW_HttpdFindHeaderField(U8 *request, char *field)
{
 const char  *endOfHeader = "\r\n\r\n";
 const char *endOfLine   = "\r\n";
 char  *header, *posi, *end;
 U8    *data;
 int   len, i;

 if (!(posi = strstr((char *)request, endOfHeader)))
  return NULL;

 len = posi - (char *)request;

 if ((header = (char *)XOAL_Mem_Malloc(len + 1)) == NULL)
 {
  LogDebug("JLW_HttpdFindHeaderField() XOAL_Mem_Malloc fail");
  return NULL;
 }
 memset(header, '\0', len + 1);

 for (i = 0; i < len; i++)
  header[i] = toupper(request[i]);

 if ((posi = strstr(header, field)))
 {
  posi += strlen(field);
  if ((end = strstr(posi, endOfLine)))
   len = end - posi;
  else
   len = strlen(posi);

  if ((data = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
  {
   LogDebug("JLW_HttpdFindHeaderField() XOAL_Mem_Malloc fail");
   JLW_XOAL_Mem_Free(header);
   return NULL;
  }
  memset(data, '\0', len + 1);

  i = posi - header;
  JLW_XOAL_Mem_Free(header);

  memcpy(data, request + i, len);
  return data;
 }

 JLW_XOAL_Mem_Free(header);
 return NULL;
}

/**
 * Function Name : JLW_HttpdFindFieldFromAll
 *
 * Function Description :
 * Input :
      U8 *request
      U8 *getData
      char *field
      int retBuffMax : retBuff의 max length
 * Output :
      U8 *retBuff
 * Return :   int    : result
*/
int JLW_HttpdFindFieldFromAll(U8 *request, U8 *getData, char *field, U8 *retBuff, int retBuffMax)
{
 int retVal;

 if (request == NULL || !strlen((char *)request) || field == NULL  || !strlen((char *)field) || retBuff == NULL || retBuffMax <= 0)
 {
  LogDebug("JLW_HttpdFindFieldFromAll() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if ((retVal = JLW_HttpdFindFieldFromGet(getData, field, retBuff, retBuffMax)) == JLW_FIELD_NOT_FOUND)
  retVal = JLW_HttpdFindFieldFromPost(request, field, retBuff, retBuffMax);

 return retVal;
}

/**
 * Function Name : JLW_HttpdFindFieldFromGet
 *
 * Function Description :
 * Input :
      U8 *getData
      char *field
      int retBuffMax : retBuff의 max length
 * Output :
      U8 *retBuff
 * Return :   int    : result
*/
int JLW_HttpdFindFieldFromGet(U8 *getData, char *field, U8 *retBuff, int retBuffMax)
{
 if (field == NULL  || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
 {
  LogDebug("JLW_HttpdFindFieldFromGet() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (getData == NULL || !strlen((char *)getData+1))
 {
  LogDebug("JLW_HttpdFindFieldFromGet() field not found");
  return JLW_FIELD_NOT_FOUND;
 }

 /* url에서 ? 위치를 가지고 오는 상황으로 이부분을 '\0' 처리가 되어 있는 상황이다. */
 return JLW_HttpdFindFieldFromRequest(getData + 1, field, retBuff, retBuffMax);
}

/**
 * Function Name : JLW_HttpdFindFieldFromPost
 *
 * Function Description :
 * Input :
      U8 *request
      char *field
      int retBuffMax : retBuff의 max length
 * Output :
      U8 *retBuff
 * Return :   int    : result
*/
int JLW_HttpdFindFieldFromPost(U8 *request, char *field, U8 *retBuff, int retBuffMax)
{
 U8 *posi;

 if (field == NULL  || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
 {
  LogDebug("JLW_HttpdFindFieldFromPost() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (request == NULL || !strlen((char *)request) || (posi = (U8 *)strstr((char *)request, g_StrHeaderEnd)) == NULL)
 {
  LogDebug("JLW_HttpdFindFieldFromPost() field not found");
  return JLW_FIELD_NOT_FOUND;
 }

 return JLW_HttpdFindFieldFromRequest(posi + strlen(g_StrHeaderEnd), field, retBuff, retBuffMax);
}

/**
 * Function Name : JLW_HttpdFindFieldFromRequest
 *
 * Function Description :
 * Input :
      U8 *buffer
      char *field
      int retBuffMax : retBuff의 max length
 * Output :
      U8 *retBuff
 * Return :   int    : result
*/
int JLW_HttpdFindFieldFromRequest(U8 *buffer, char *field, U8 *retBuff, int retBuffMax)
{
 char *posi, *end;
 int  len;

 if (field == NULL  || !strlen(field) || retBuff == NULL || retBuffMax <= 0)
 {
  LogDebug("JLW_HttpdFindFieldFromRequest() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (buffer == NULL || !strlen((char *)buffer))
 {
  LogDebug("JLW_HttpdFindFieldFromRequest() field not found");
  return JLW_FIELD_NOT_FOUND;
 }

 if ((posi = strstr((char *)buffer, field)))
 {
  if ((posi == (char *)buffer) || (*(posi-1) == '&'))
  {
   posi += strlen(field);
   if (*posi == '\'' || *posi == '\"')
   {
    if (((end = strchr(posi+1, *posi)) == NULL) || ((end[1] != '\0') && (end[1] != '&') ))
    {
     LogDebug("JLW_HttpdFindFieldFromRequest() data error");
     return JLW_DATA_ERROR;
    }
    posi++;

    len = end - posi;
    if (len > retBuffMax)
    {
     LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
     return JLW_BUFFER_OVERFLOW;
    }
    memcpy(retBuff, posi, len);
    retBuff[len] = '\0';
   } else {
    if ((end = strchr(posi, '&')))
    {
     len = end - posi;
     if (len > retBuffMax)
     {
      LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
      return JLW_BUFFER_OVERFLOW;
     }
     memcpy(retBuff, posi, len);
     retBuff[len] = '\0';
    } else {
     if (strlen(posi) > retBuffMax)
     {
      LogDebug("JLW_HttpdFindFieldFromRequest() data length over");
      return JLW_BUFFER_OVERFLOW;
     }
     strcpy((char *)retBuff, posi);
    }
   }
   return JLW_WORK_OK;
  }
 }

 LogDebug("JLW_HttpdFindFieldFromRequest() field not found");
 return JLW_FIELD_NOT_FOUND;
}

/**
 * Function Name : JLW_HttpdConv2Char
 *
 * Function Description :
 * Input :
 * Output :
      U8 *buffer
 * Return :
*/
void JLW_HttpdConv2Char(U8 *buffer)
{
 U8  *posi, *prev;
 char  data[3];
 int  ch;

 prev = buffer;
 while ((posi = (U8 *)strchr((char *)prev, '%')))
 {
  if (strlen((char *)posi) <= 3)
   return;

  if (posi[1] == '%')
   continue;

  memset(data, '\0', sizeof(data));
  data[0] = toupper(posi[1]);
  data[1] = toupper(posi[2]);

  sscanf(data, "%X", &ch);

  *posi = (U8)(ch & 0xFF);

  strcpy((char *)posi + 1, (char *)posi + 3);
 }
}
----------------------------------------------------------------
CGI functions
----------------------------------------------------------------

/**
 * Function Name : JLW_HTTPD_CGIWork
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     int httpWorkFlag
     JLW_WorkBuff *urlBuff
     char *urlPosi
     U32 contLen
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_CGIWork(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
       JLW_WorkBuff *urlBuff, char *urlPosi, U32 contLen)
{
 char *posi;

 if (sock < 0 || servInfo == NULL || recvBuff == NULL || urlBuff == NULL)
 {
  LogDebug("JLW_HTTPD_CGIWork() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (urlBuff->buff[0] == '/' || urlBuff->buff[0] == '\\')
  posi = (char *)urlBuff->buff+1;
 else
  posi = (char *)urlBuff->buff;

 if (!strcmp(posi, "Dir.do"))
 {
  return JLW_HTTPD_Dir(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
 } else if (!strcmp(posi, "RmDir.do")) {
  return JLW_HTTPD_RmDir(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
#if 0
 } else if (!strcmp(posi, "MkDir.do")) {
#endif
 } else if (!strcmp(posi, "ViewFile.do")) {
  return JLW_HTTPD_ViewFile(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
 } else if (!strcmp(posi, "DeleteFile.do")) {
  return JLW_HTTPD_DeleteFile(sock, servInfo, recvBuff, httpWorkFlag, urlBuff, urlPosi);
 } else if (!strcmp(posi, "UploadFileHtml.do")) {
  return JLW_HTTPD_UploadFileHttp(sock, servInfo);
 } else if (!strcmp(posi, "UploadFile.do")) {
  if (httpWorkFlag != HTTPD_COMMAND_POST)
   return JLW_WORK_FAIL;
  return JLW_HTTPD_UploadFile(sock, servInfo, recvBuff, contLen);
 }

 return JLW_WORK_FAIL;
}

/**
 * Function Name : JLW_HTTPD_Dir
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     int httpWorkFlag
     JLW_WorkBuff *urlBuff
     char *urlPosi
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_Dir(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
      JLW_WorkBuff *urlBuff, char *urlPosi)
{
 const char  httpBodyHead[] =
    "<HTML><HEAD><TITLE>Directory</TITLE></HEAD><BODY>\r\n";
 const char  strPathName[] = "pathName=";
 char  pathName[HTTPD_MAX_PATH+1];
 int   retVal;

 memset(pathName, '\0', sizeof(pathName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
             (U8 *)pathName, sizeof(pathName)-1);
 if (retVal && retVal != JLW_FIELD_NOT_FOUND)
  return retVal;

 return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, httpBodyHead);
}

/**
 * Function Name : JLW_HTTPD_RmDir
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     int httpWorkFlag
     JLW_WorkBuff *urlBuff
     char *urlPosi
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_RmDir(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
     JLW_WorkBuff *urlBuff, char *urlPosi)
{
 const char  httpBodyHead[] =
    "<HTML><HEAD><TITLE>Rm Dir</TITLE></HEAD><BODY>\r\n"
    "rmdir %s %s<br><br>\r\n";
 const char  strPathName[] = "pathName=";
 char  pathName[HTTPD_MAX_PATH+1], buffer[HTTPD_BUFF_SIZE+HTTPD_MAX_PATH+1], *posi;
 int   retVal;

 memset(pathName, '\0', sizeof(pathName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
             (U8 *)pathName, sizeof(pathName)-1);
 if (retVal)
  return retVal;

 JLW_ConvPathName(pathName);

 if (strlen(pathName) == 1 && pathName[0] == '\\')
  posi = (char *)g_failText;
 else {
#ifndef __NO_VDMS__
  if (!XOAL_F_RmDir(XOAL_F_GetDefaultDrive(), pathName))
#else
  if (0)
#endif
   posi = (char *)g_failText;
  else
   posi = (char *)g_successText;
 }
 sprintf(buffer, httpBodyHead, pathName, posi);

 if (strlen(pathName) != 1 || pathName[0] != '\\')
  if ((posi = strrchr(pathName, '\\')))
   *posi = '\0';

 return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, buffer);
}

/**
 * Function Name : JLW_HTTPD_ViewFile
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     int httpWorkFlag
     JLW_WorkBuff *urlBuff
     char *urlPosi
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_ViewFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
        JLW_WorkBuff *urlBuff, char *urlPosi)
{
 const char  strPathName[] = "pathName=";
 const char  strFileName[] = "fileName=";
 char  pathName[HTTPD_MAX_PATH+1], fileName[HTTPD_SMALL_BUFF_SIZE+1];
 int   retVal;

 memset(pathName, '\0', sizeof(pathName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
             (U8 *)pathName, sizeof(pathName)-1);
 if (retVal)
  return retVal;

 memset(fileName, '\0', sizeof(fileName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strFileName, (U8 *)fileName, sizeof(fileName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strFileName,
             (U8 *)fileName, sizeof(fileName)-1);
 if (retVal)
  return retVal;

 JLW_ConvPathName(pathName);

 return JLW_HTTPD_SendFile(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, fileName);
}

/**
 * Function Name : JLW_HTTPD_DeleteFile
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     int httpWorkFlag
     JLW_WorkBuff *urlBuff
     char *urlPosi
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_DeleteFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, int httpWorkFlag,
       JLW_WorkBuff *urlBuff, char *urlPosi)
{
 const char  httpBodyHead[] =
    "<HTML><HEAD><TITLE>Delete file</TITLE></HEAD><BODY>\r\n"
    "delete file : path=%s file=%s %s<br><br>\r\n";
 const char  strPathName[] = "pathName=";
 const char  strFileName[] = "fileName=";
 char  pathName[HTTPD_MAX_PATH+1], fileName[HTTPD_SMALL_BUFF_SIZE+1], buffer[HTTPD_BUFF_SIZE+HTTPD_MAX_PATH+1], *posi;
 int   retVal;

 memset(pathName, '\0', sizeof(pathName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strPathName, (U8 *)pathName, sizeof(pathName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strPathName,
             (U8 *)pathName, sizeof(pathName)-1);
 if (retVal)
  return retVal;

 memset(fileName, '\0', sizeof(fileName));
 if (httpWorkFlag == HTTPD_COMMAND_GET)
  retVal = JLW_HttpdFindFieldFromGet((U8 *)urlPosi, (char *)strFileName, (U8 *)fileName, sizeof(fileName)-1);
 else
  retVal = JLW_HttpdFindFieldFromAll(recvBuff->buff, (U8 *)urlPosi, (char *)strFileName,
             (U8 *)fileName, sizeof(fileName)-1);
 if (retVal)
  return retVal;

 JLW_ConvPathName(pathName);

#ifndef __NO_VDMS__
 if (!XOAL_F_Remove(XOAL_F_GetDefaultDrive(), pathName, fileName))
#else
 if (0)
#endif
  posi = (char *)g_failText;
 else
  posi = (char *)g_successText;

 sprintf(buffer, httpBodyHead, pathName, fileName, posi);

 return JLW_HTTPD_DirResponse(sock, servInfo, XOAL_F_GetDefaultDrive(), pathName, buffer);
}

/**
 * Function Name : JLW_HTTPD_DirResponse
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     int device
     char *pathName
     char *httpBodyHeader
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_DirResponse(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int device, char *pathName,
        const char *httpBodyHead)
{
#if 0
 const char httpBodyHead[] =
    "<HTML><HEAD><TITLE>Directory</TITLE></HEAD><BODY>\r\n";
#endif
 const char httpBodyTableStart[] =
    "%s >><br><TABLE BORDER=1>\r\n";
 const char httpBodyTail[] =
    "</TABLE></BODY></HTML>";
 const char httpBodyTableParent[] =
    "<TR><TD colspan=3><A HREF=\"Dir.do?pathName='%s'\">[..]</A></TD></TR>\r\n";
 const char httpBodyTableDir[] =
    "<TR><TD><A HREF=\"Dir.do?pathName='%s%s%s'\">[%s]</A></TD><TD>%lu</TD>"
    "<TD><A HREF=\"RmDir.do?pathName='%s%s%s'\"><IMG border=0 src=\"image/btn_delete.gif\"></A></TD></TR>\r\n";
 const char httpBodyTableFile[] =
    "<TR><TD><A HREF=\"ViewFile.do?pathName='%s'&fileName='%s'\">%s</A></TD><TD>%lu</TD>"
    "<TD><A HREF=\"DeleteFile.do?pathName='%s'&fileName='%s'\"><IMG border=0 src=\"image/btn_delete.gif\"></A></TD></TR>\r\n";
 const char strSearch[] = "*";

#ifndef __NO_VDMS__
 XOF_FILEINFO *fileInfo;
 XOF_HFIND  *findHandle;
#else
 XOF_FILEINFO fileInfo;
 XOF_HFIND  findHandle;
#endif
 char   fullPath[HTTPD_MAX_PATH+1], fileSize[40], pathEnd[2], *posi;
 unsigned long  bodylen, pathLen;
 JLW_WorkBuff headBuff, bodyBuff;
 int    retVal;

 if (sock < 0 || servInfo == NULL)
 {
  LogDebug("JLW_HTTPD_DirResponse() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (pathName == NULL)
  pathName = "";

 JLW_ConvPathName(pathName);
 if (pathName[0] != '\\')
  sprintf(fullPath, "\\%s", pathName);
 else
  strcpy(fullPath, pathName);

 pathLen = strlen(fullPath);
 if (pathLen > 1 && fullPath[pathLen-1] == '\\')
 {
  fullPath[pathLen-1] = '\0';
  pathLen--;
 }

 bodylen = strlen(httpBodyHead) + strlen(httpBodyTableStart) - 1 * 2 + pathLen + strlen(httpBodyTail);
 if (pathLen > 1)
 {
   bodylen += strlen(httpBodyTableParent) - 1 * 2;

   posi = strrchr(fullPath, '\\');
   if (posi == fullPath)
   bodylen += 1;
  else {
   bodylen += (posi - fullPath);
  }
  strcpy(pathEnd, "\\");
 } else {
  memset(pathEnd, '\0', sizeof(pathEnd));
 }

 /* directory */
 findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_DIR, &fileInfo);
#ifndef __NO_VDMS__
 if (findHandle != NULL)
#else
 if (findHandle != INVALID_HANDLE_VALUE)
#endif
 {
  do {
#ifndef __NO_VDMS__
   if (fileInfo)
#endif
   {
#ifdef __NO_VDMS__
    if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
     continue;
    if (!strcmp(fileInfo.cFileName, ".") || !strcmp(fileInfo.cFileName, ".."))
     continue;
#endif
    bodylen += (strlen(httpBodyTableDir) - 7 * 2 - 1 * 3 + pathLen * 2 + strlen(pathEnd) * 2
#ifndef __NO_VDMS__
       + strlen(fileInfo->szFileName) * 3);
    sprintf(fileSize, "%lu", fileInfo->uiFileSize);
#else
       + strlen(fileInfo.cFileName) * 3);
    sprintf(fileSize, "%lu", (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow);
#endif
    bodylen += strlen(fileSize);
   }
  } while (XOAL_F_FindNext(findHandle, &fileInfo));
  XOAL_F_FindClose(findHandle);
 }

 /* file */
 findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_NORMAL, &fileInfo);
#ifndef __NO_VDMS__
 if (findHandle != NULL)
#else
 if (findHandle != INVALID_HANDLE_VALUE)
#endif
 {
  do {
#ifndef __NO_VDMS__
   if (fileInfo)
#endif
   {
#ifdef __NO_VDMS__
    if ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
     continue;
#endif
    bodylen += (strlen(httpBodyTableFile) - 5 * 2 - 1 * 3 + pathLen * 2
#ifndef __NO_VDMS__
       + strlen(fileInfo->szFileName) * 3);
    sprintf(fileSize, "%lu", fileInfo->uiFileSize);
#else
       + strlen(fileInfo.cFileName) * 3);
    sprintf(fileSize, "%lu", (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow);
#endif
    bodylen += strlen(fileSize);
   }
  } while (XOAL_F_FindNext(findHandle, &fileInfo));
  XOAL_F_FindClose(findHandle);
 }

 /* header make & send */
 if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodylen, &headBuff)))
  return retVal;
 retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
 JLW_XOAL_Mem_Free(headBuff.buff);
 if (retVal)
  return retVal;

 if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(HTTPD_MAX_PATH * 2 + HTTPD_BUFF_SIZE + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_DirResponse() XOAL_Mem_Malloc fail");
  return JLW_MEMORY_ALLOC_FAIL;
 }

 sprintf((char *)bodyBuff.buff, httpBodyHead);
 bodyBuff.len = strlen((char *)bodyBuff.buff);
 if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }
 sprintf((char *)bodyBuff.buff, httpBodyTableStart, fullPath);
 bodyBuff.len = strlen((char *)bodyBuff.buff);
 if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }
 if (pathLen > 1)
 {
   posi = strrchr(fullPath, '\\');
   if (posi == fullPath)
   sprintf((char *)bodyBuff.buff, httpBodyTableParent, "\\");
  else {
   *posi = '\0';
   sprintf((char *)bodyBuff.buff, httpBodyTableParent, fullPath);
   *posi = '\\';
  }
  bodyBuff.len = strlen((char *)bodyBuff.buff);
  if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
  {
   JLW_XOAL_Mem_Free(bodyBuff.buff);
   return retVal;
  }
 }

 /* directory */
 findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_DIR, &fileInfo);
#ifndef __NO_VDMS__
 if (findHandle != NULL)
#else
 if (findHandle != INVALID_HANDLE_VALUE)
#endif
 {
  do {
#ifndef __NO_VDMS__
   if (fileInfo)
#endif
   {
#ifdef __NO_VDMS__
    if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      || (fileInfo.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
     continue;
    if (!strcmp(fileInfo.cFileName, ".") || !strcmp(fileInfo.cFileName, ".."))
     continue;
#endif

    sprintf((char *)bodyBuff.buff, httpBodyTableDir,
#ifndef __NO_VDMS__
      fullPath, pathEnd, fileInfo->szFileName, fileInfo->szFileName,
      fileInfo->uiFileSize,
      fullPath, pathEnd, fileInfo->szFileName);
#else
      fullPath, pathEnd, fileInfo.cFileName, fileInfo.cFileName,
      (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow,
      fullPath, pathEnd, fileInfo.cFileName);
#endif
    bodyBuff.len = strlen((char *)bodyBuff.buff);
    if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
    {
     JLW_XOAL_Mem_Free(bodyBuff.buff);
     XOAL_F_FindClose(findHandle);
     return retVal;
    }
   }
  } while (XOAL_F_FindNext(findHandle, &fileInfo));
  XOAL_F_FindClose(findHandle);
 }

 /* file */
 findHandle = XOAL_F_FindFirst(device, fullPath, (char *)strSearch, JFS_ATTR_NORMAL, &fileInfo);
#ifndef __NO_VDMS__
 if (findHandle != NULL)
#else
 if (findHandle != INVALID_HANDLE_VALUE)
#endif
 {
  do {
#ifndef __NO_VDMS__
   if (fileInfo)
#endif
   {
#ifdef __NO_VDMS__
    if ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      || (fileInfo.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)))
     continue;
#endif
    sprintf((char *)bodyBuff.buff, httpBodyTableFile,
#ifndef __NO_VDMS__
      fullPath, fileInfo->szFileName, fileInfo->szFileName,
      fileInfo->uiFileSize,
      fullPath, fileInfo->szFileName);
#else
      fullPath, fileInfo.cFileName, fileInfo.cFileName,
      (fileInfo.nFileSizeHigh * (MAXDWORD+1)) + fileInfo.nFileSizeLow,
      fullPath, fileInfo.cFileName);
#endif
    bodyBuff.len = strlen((char *)bodyBuff.buff);
    if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
    {
     JLW_XOAL_Mem_Free(bodyBuff.buff);
     XOAL_F_FindClose(findHandle);
     return retVal;
    }
   }
  } while (XOAL_F_FindNext(findHandle, &fileInfo));
  XOAL_F_FindClose(findHandle);
 }

 sprintf((char *)bodyBuff.buff, httpBodyTail);
 bodyBuff.len = strlen((char *)bodyBuff.buff);
 retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);

 JLW_XOAL_Mem_Free(bodyBuff.buff);
 return retVal;
}

/**
 * Function Name : JLW_HTTPD_UploadFileHttp
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_UploadFileHttp(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo)
{
 const char httpBody[] =
    "<HTML><HEAD><TITLE>File upload For WEB</TITLE></HEAD>\r\n"
    "<BODY><Form action=\"UploadFile.do\" Method=\"POST\" enctype=\"multipart/form-data\">\r\n"
    "Path : <Input type=\"TEXT\" name=\"pathName\"><br>\r\n"
    "File : <Input type=\"FILE\" name=\"fileName\"><br>\r\n"
    "<Input type=\"SUBMIT\" value=\"Send\"></Form></BODY></HTML>\r\n";
 JLW_WorkBuff headBuff, bodyBuff;
 int    retVal;

 if (sock < 0 || servInfo == NULL)
 {
  LogDebug("JLW_HTTPD_UploadFileHttp() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 bodyBuff.buff = (U8 *)httpBody;
 bodyBuff.len  = strlen(httpBody);

 /* header make & send */
 if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodyBuff.len, &headBuff)))
  return retVal;
 retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
 JLW_XOAL_Mem_Free(headBuff.buff);
 if (retVal)
  return retVal;

 /* body send */
 return JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);
}

/**
 * Function Name : JLW_HTTPD_UploadFile
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     JLW_WorkBuff *recvBuff
     U32 contLen
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_UploadFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, JLW_WorkBuff *recvBuff, U32 contLen)
{
 const char httpBody[] =
    "<HTML><HEAD><TITLE>File upload For WEB</TITLE></HEAD>\r\n"
    "<BODY>Path : %s<BR>File : %s<BR>Upload Result : %s<BR>\r\n"
    "<Form action=\"UploadFile.do\" Method=\"POST\" enctype=\"multipart/form-data\">\r\n"
    "Path : <Input type=\"TEXT\" name=\"pathName\"><br>\r\n"
    "File : <Input type=\"FILE\" name=\"fileName\"><br>\r\n"
    "<Input type=\"SUBMIT\" value=\"Send\"></Form></BODY></HTML>\r\n";

 char    fileName[HTTPD_SMALL_BUFF_SIZE+1], pathName[HTTPD_MAX_PATH+1], *boundary, *posi;
 JLW_WorkBuff  pathBuff, headBuff, bodyBuff;
 int    len, retVal;

 if (sock < 0 || servInfo == NULL || recvBuff == NULL || !contLen)
 {
  LogDebug("JLW_HTTPD_UploadFile() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if (contLen <= HTTPD_NO_SAVE_CONTENT_LEN)
 { /* content length가 저장 크기보다 적어 http body가 file로 생성되지 않은경우 file로 만든다 */
  if ((posi = strstr((char *)recvBuff->buff, g_StrHeaderEnd)) == NULL)
  {
   LogDebug("JLW_HTTPD_UploadFile() receive data error");
   return JLW_WORK_FAIL;
  }
  posi += strlen(g_StrHeaderEnd);

  JLW_HTTPD_RecvFile(sock, servInfo->recvTime, contLen, XOAL_F_GetDefaultDrive(),
   g_recvTempPath, g_recvTempFile, (U8 *)posi, contLen);
  *posi = '\0';
 }

 /* header에서 boundary 를 찾는다 */
 if ((boundary = (char *)JLW_HttpdFindHeaderField(recvBuff->buff, "BOUNDARY=")) == NULL)
 {
  LogDebug("JLW_HTTPD_UploadFile() boundary not found");
  return JLW_BOUNDARY_NOT_FOUND;
 }
 if ((posi = strchr(boundary, ';')))
  *posi = '\0';

 /* http body에서 pathName field를 구하고 directory를 생성한다. */
 if ((retVal = JLW_HTTPD_GetFieldFromFile("pathName", boundary, XOAL_F_GetDefaultDrive(),
   g_recvTempPath, g_recvTempFile, &pathBuff)))
 {
  JLW_XOAL_Mem_Free(boundary);
  return retVal;
 }
// JLW_Makedir(g_httpBasePath, (char *)pathBuff.buff, pathName);
#ifndef __NO_VDMS__
 JLW_Makedir("", (char *)pathBuff.buff, pathName);
#else
 JLW_Makedir(g_httpBasePath, (char *)pathBuff.buff, pathName);  // web directory로만 upload한다.
#endif

 /* http body에서 fileName field를 구하고, file로 생성한다. */
 retVal = JLW_HTTPD_MakeFile("fileName", boundary, XOAL_F_GetDefaultDrive(),
   g_recvTempPath, g_recvTempFile, XOAL_F_GetDefaultDrive(), pathName, fileName, sizeof(fileName)-1);
 JLW_XOAL_Mem_Free(boundary);
 if (retVal)
  posi = (char *)g_failText;
 else
  posi = (char *)g_successText;

 bodyBuff.len = strlen(httpBody) + strlen((char *)pathBuff.buff) + strlen(fileName) + strlen(posi) - 3 * 2;
 if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(bodyBuff.len + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_UploadFile() XOAL_Mem_Malloc fail");
  JLW_XOAL_Mem_Free(pathBuff.buff);

  return JLW_MEMORY_ALLOC_FAIL;
 }
 sprintf((char *)bodyBuff.buff, httpBody, pathBuff.buff, fileName, posi);
 JLW_XOAL_Mem_Free(pathBuff.buff);

 if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, bodyBuff.len, &headBuff)))
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }

 /* header make & send */
 retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
 JLW_XOAL_Mem_Free(headBuff.buff);
 if (retVal)
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }

 retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime);
 JLW_XOAL_Mem_Free(bodyBuff.buff);
 return retVal;
}
----------------------------------------------------------------
Message functions
----------------------------------------------------------------

/** 공통사용 http text 선언
 */
const char g_StrHeaderEnd[] = "\r\n\r\n";
const char g_StrCrLf[]      = "\r\n";
const char g_successText[]   = "success";
const char g_failText[]      = "fail";

/**
 * Function Name : JLW_HTTPD_MakeHttpdHeader
 *
 * Function Description :
 * Input :
     char *status
     int bodyLength
 * Output :
     JLW_WorkBuff *retBuff : return buffer data & length
 * Return :  int      : result
*/
int JLW_HTTPD_MakeHttpdHeader(const char *status, U32 bodyLength, JLW_WorkBuff *retBuff)
{
 const char headerFormat[] = "HTTP/1.1 %s\r\n"
        "Connection: close\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: %u\r\n"
        "Cache-Control: no-cache\r\n"
        "\r\n";

 char temp[50];
 U32  len;

 memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
 if (status == NULL || !strlen(status) || bodyLength < 0 || retBuff == NULL)
 {
  LogDebug("JLW_HTTPD_MakeHttpdHeader() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 len = strlen(headerFormat) + strlen(status) - 2 * 2;
 sprintf(temp, "%u", bodyLength);
 len += strlen(temp);

 if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_MakeHttpdHeader() XOAL_Mem_Malloc fail");
  return JLW_MEMORY_ALLOC_FAIL;
 }

 retBuff->len = len;
 memset(retBuff->buff, '\0', len + 1);
 sprintf((char *)retBuff->buff, headerFormat, status, bodyLength);

#if 0
 {
  U8  temp[101];
  int  i;

  LogDebug("JLW_HTTPD_MakeHttpdHeader() len=%d", len);
  for (i = 0; i < len; i+= 100)
  {
   strncpy(temp, retBuff->buff+i, 100);
   LogDebug("%s", temp);
  }
 }
#endif

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_HTTPD_MakeHttpdImageHeader
 *
 * Function Description :
 * Input :
     char *status
     int bodyLength
     char *contentType
 * Output :
     JLW_WorkBuff *retBuff : return buffer data & length
 * Return :  int      : result
*/
int JLW_HTTPD_MakeHttpdOtherHeader(const char *status, U32 bodyLength, JLW_WorkBuff *retBuff, char *contentType)
{
 const char headerFormat[] = "HTTP/1.1 %s\r\n"
        "Connection: close\r\n"
        "Content-Type: %s\r\n"
        "Content-Length: %u\r\n"
        "Cache-Control: no-cache\r\n"
        "\r\n";
 char temp[50];
 U32  len;

 memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
 if (status == NULL || !strlen(status) || bodyLength < 0 || retBuff == NULL)
 {
  LogDebug("JLW_HTTPD_MakeHttpdImageHeader() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 len = strlen(headerFormat) - 3 * 2 + strlen(status) + strlen(contentType);
 sprintf(temp, "%u", bodyLength);
 len += strlen(temp);

 if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_MakeHttpdImageHeader() XOAL_Mem_Malloc fail");
  return JLW_MEMORY_ALLOC_FAIL;
 }

 retBuff->len = len;
 memset(retBuff->buff, '\0', len + 1);
 sprintf((char *)retBuff->buff, headerFormat, status, contentType, bodyLength);

#if 0
 {
  U8  temp[101];
  int  i;

  LogDebug("JLW_HTTPD_MakeHttpdImageHeader() len=%d", len);
  for (i = 0; i < len; i+= 100)
  {
   strncpy(temp, retBuff->buff+i, 100);
   LogDebug("%s", temp);
  }
 }
#endif

 return JLW_WORK_OK;
}

----------------------------------------------------------------
File handle functions
----------------------------------------------------------------

/**
 * Function Name : JLW_HTTPD_SendFile
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     JLW_HttpdServerInfo *servInfo
     int device
     U8 *pathName
     char *fileName
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_SendFile(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int device, char *pathName, char *fileName)
{
 JLW_WorkBuff headBuff, bodyBuff;
 char   *posi, *contentType;
 bool   isText = TRUE;
 XOF_FILE  *readFp;
 U32    fileLen;
 int    retVal, readLen;

 if (sock < 0 || servInfo == NULL || device < 0 || pathName == NULL || fileName == NULL || !strlen(fileName))
 {
  LogDebug("JLW_HTTPD_SendFile() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 if ((posi = strrchr(fileName, '.')) != NULL)
 {
  if ((contentType = JLW_GetMimeType(posi + 1)) != NULL)
   if (!strstr(contentType, "text/"))
    isText = FALSE;
 }

 JLW_ConvPathName(pathName);
#ifndef __NO_VDMS__
 if ((readFp = XOAL_F_Open(device, pathName, fileName, DCA_READ | DCA_BINARY)) == NULL)
#else
 if ((readFp = XOAL_F_Open(device, pathName, fileName, "rb")) == NULL)
#endif
 {
  LogDebug("JLW_HTTPD_SendFile() file open error %d:%s/%s", device, pathName, fileName);
  return JLW_FILE_OPEN_FAIL;
 }
 fileLen = XOAL_F_Size(readFp);

 if (isText)
 {
  if ((retVal = JLW_HTTPD_MakeHttpdHeader(g_strHttpStatus200, fileLen, &headBuff)))
  {
   XOAL_F_Close(readFp);
   return retVal;
  }
 } else {
  if ((retVal = JLW_HTTPD_MakeHttpdOtherHeader(g_strHttpStatus200, fileLen, &headBuff, contentType)))
  {
   XOAL_F_Close(readFp);
   return retVal;
  }
 }

 retVal = JLW_Httpd_Send(sock, &headBuff, servInfo->sendTime);
 JLW_XOAL_Mem_Free(headBuff.buff);
 if (retVal)
 {
  XOAL_F_Close(readFp);
  return retVal;
 }

 if ((bodyBuff.buff = (U8 *)XOAL_Mem_Malloc(HTTPD_SEND_FILE_BUFF + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_SendFile() XOAL_Mem_Malloc fail");
  XOAL_F_Close(readFp);
  return JLW_MEMORY_ALLOC_FAIL;
 }

 while (!XOAL_F_EOF(readFp))
 {
  memset(bodyBuff.buff, '\0', HTTPD_SEND_FILE_BUFF+1);
  if ((readLen = XOAL_F_Read(readFp, bodyBuff.buff, HTTPD_SEND_FILE_BUFF)) < 0)
  {
   LogDebug("JLW_HTTPD_SendFile() XOAL_F_Read error");
   break;
  }

  bodyBuff.len  = readLen;
  if ((retVal = JLW_Httpd_Send(sock, &bodyBuff, servInfo->sendTime)))
  {
   LogDebug("JLW_HTTPD_SendFile() file JLW_Httpd_Send error");
   JLW_XOAL_Mem_Free(bodyBuff.buff);
   XOAL_F_Close(readFp);

   return retVal;
  }
 }

 JLW_XOAL_Mem_Free(bodyBuff.buff);
 XOAL_F_Close(readFp);

 return JLW_WORK_OK;

}

/**
 * Function Name : JLW_HTTPD_RecvFile
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     int receiveTimeout
     U32 fileLen
     int device
     char *pathName
     char *fileName
     U8 *before
     int beforeLen
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_RecvFile(XONS_SOCKET sock, int receiveTimeout, U32 fileLen, int device, char *pathName, char *fileName,
  U8 *before, int beforeLen)
{
 U8    *buffer;
 XOF_FILE  *writeFp;
 U32    recvTotal;
 int    retVal, recvLen, writeTotal, selectCnt, len;
 XONS_FDSET  readFds, exceptFds;
 XONS_TIMEVAL timeout;

 if (sock < 0 || device < 0 || pathName == NULL || fileName == NULL || !strlen(fileName))
 {
  LogDebug("JLW_HTTPD_RecvFile() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 JLW_Mkdir(device, pathName,FALSE);
#ifndef __NO_VDMS__
 if ((writeFp = XOAL_F_Open(device, pathName, fileName, DCA_WRITE | DCA_CREATE | DCA_BINARY)) == NULL)
#else
 if ((writeFp = XOAL_F_Open(device, pathName, fileName, "w+b")) == NULL)
#endif
 {
  LogDebug("JLW_HTTPD_RecvFile() file open error %d:%s/%s", device, pathName, fileName);
  return JLW_FILE_OPEN_FAIL;
 }

 if (before != NULL && beforeLen)
 {
  writeTotal = 0;
  while (beforeLen > writeTotal)
  {
   if ((len = XOAL_F_Write(writeFp, before + writeTotal, beforeLen - writeTotal)) == -1)
   {
    LogDebug("JLW_HTTPD_RecvFile() XOAL_F_Write fail");
    XOAL_F_Close(writeFp);

    return JLW_FILE_WRITE_FAIL;
   }
   writeTotal += len;
  }
  fileLen -= beforeLen;
 }

 if ((buffer = (U8 *)XOAL_Mem_Malloc(HTTPD_RECV_FILE_BUFF + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_RecvFile() XOAL_Mem_Malloc fail");
  XOAL_F_Close(writeFp);
  return JLW_MEMORY_ALLOC_FAIL;
 }

 for (recvTotal = 0; recvTotal < fileLen; recvTotal += recvLen)
 {
#ifdef __XOAL__SELECT__OK__
  if (receiveTimeout > 0)
  {
   XOAL_NS_FD_ZERO(&readFds);
   XOAL_NS_FD_ZERO(&exceptFds);
   XOAL_NS_FD_SET(sock, &readFds);
   XOAL_NS_FD_SET(sock, &exceptFds);

   timeout.tv_sec  = receiveTimeout / 1000;
   timeout.tv_usec = receiveTimeout % 1000;

#if 0
   if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, &exceptFds, &timeout)) <= 0
     || XOAL_NS_FD_ISSET(sock, &exceptFds))
#endif
   if ((selectCnt = XOAL_NS_Select(sock+1, &readFds, NULL, NULL, &timeout)) <= 0)
   {
    LogDebug("JLW_HTTPD_RecvFile() XOAL_NS_Select readFds error %d", selectCnt);
    JLW_XOAL_Mem_Free(buffer);
    XOAL_F_Close(writeFp);

    return JLW_NET_RECV_FAIL;
   }
  }
#endif

  if ((recvLen = XOAL_NS_Recv(sock, buffer, HTTPD_RECV_FILE_BUFF, 0)) <= 0)
  {
   LogDebug("JLW_HTTPD_RecvFile() XOAL_NS_Recv fail");
   JLW_XOAL_Mem_Free(buffer);
   XOAL_F_Close(writeFp);

   return JLW_NET_RECV_FAIL;
  }

  writeTotal = 0;
  while (recvLen > writeTotal)
  {
   if ((len = XOAL_F_Write(writeFp, buffer + writeTotal, recvLen - writeTotal)) == -1)
   {
    LogDebug("JLW_HTTPD_RecvFile() XOAL_F_Write fail");
    JLW_XOAL_Mem_Free(buffer);
    XOAL_F_Close(writeFp);

    return JLW_FILE_WRITE_FAIL;
   }
   writeTotal += len;
  }
 }

 JLW_XOAL_Mem_Free(buffer);
 XOAL_F_Close(writeFp);

 return JLW_WORK_OK;

}

/**
 * Function Name : JLW_HTTPD_MakeFile
 *
 * Function Description :
 * Input :
     char *field
     char *boundary
     int deviceR, char *pathNameR, char *fileNameR
    int deviceW, char *pathNameW, int fileNameWLen
 * Output :
     char *fileNameW   : return fileName to write
 * Return :  int      : result
*/
int JLW_HTTPD_MakeFile(char *field, char *boundary, int deviceR, char *pathNameR, char *fileNameR,
  int deviceW, char *pathNameW, char *fileNameW, int fileNameWLen)
{
 const char  strBoundary[]   = "\r\n--";
 const char  g_StrCrLf[]       = "\r\n";
 const char  strRequestEnd[] = "--";
 const char  strName[]       = "name=";
 const char  strFileName[]   = "filename=";
 char   temp[HTTPD_BUFF_SIZE+1], *posi;
 XOF_FILE *readFp, *writeFp;
 U8    buffer[2];
 int   loop, check, workStep, flag, retVal;

 if (field == NULL || !strlen(field) || boundary == NULL  || !strlen(boundary)
    || deviceR < 0 || pathNameR == NULL || fileNameR == NULL || !strlen(fileNameR)
    || deviceW < 0 || pathNameW == NULL || fileNameW == NULL || fileNameWLen <= 0)
 {
  LogDebug("JLW_HTTPD_MakeFile() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

#ifndef __NO_VDMS__
 if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, DCA_READ | DCA_BINARY)) == NULL)
#else
 if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, "rb")) == NULL)
#endif
 {
  LogDebug("JLW_HTTPD_MakeFile() file open error %d:%s/%s", deviceR, pathNameR, fileNameR);
  return JLW_FILE_OPEN_FAIL;
 }

 memset(fileNameW, '\0', fileNameWLen+1);
 memset(temp,      '\0', sizeof(temp));
 memset(buffer,    '\0', sizeof(buffer));

 check   = 2;  /* file로 저장된 request는 boundary부터 저장된다 */
 workStep = 0;  /* 0인경우 boundary를 찾음
             1인경우 field를 찾음
             2인경우 filename을 찾음
             3인경우 read start 위치를 찾음 */
 while(!XOAL_F_EOF(readFp))
 {
  if (XOAL_F_Read(readFp, buffer, 1) != 1)
  {
   LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Read error");
   XOAL_F_Close(readFp);
   return JLW_FIELD_NOT_FOUND;
  }

  if (!workStep)
  {
   if (!check)          /* boundary 시작위치를 찾는다 */
   {
    if (buffer[0] == strBoundary[check])
     check++;
    continue;
   } else if (check < strlen(strBoundary)) {  /* boundary 시작위치를 찾는다 */
    if (buffer[0] == strBoundary[check])
    {
     check++;
     continue;
    }
   } else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
    if (buffer[0] == boundary[check - strlen(strBoundary)])
    {
     check++;
     continue;
    }
   } else {
    if (buffer[0] == g_StrCrLf[check - strlen(strBoundary) - strlen(boundary)])
    {
     check++;
     if (check >= (strlen(strBoundary) + strlen(boundary) + strlen(g_StrCrLf)))
     {        /* boundary를 찾음 */
      workStep = 1;
      check    = 0;
     }
     continue;
    }
   }
   check = 0;
   if (buffer[0] == strBoundary[check])
    check++;
  } else if (workStep == 1) {
   if (check < strlen(strName))   /* name 시작위치를 찾는다 */
   {
    if (buffer[0] == strName[check])
     check++;
    else
     check = 0;
   } else {
    if (check == strlen(strName))
    {
     if (buffer[0] == '\"' || buffer[0] == '\'')
     {
      flag = 1;
      check++;
      continue;
     } else
      flag = 0;
    }

    if (check == (strlen(strName) + strlen(field) + flag))
    {
     check    = 0;
     if ((flag && (buffer[0] == '\"' || buffer[0] == '\''))
      || (!flag && buffer[0] == ';'))
     {
      workStep = 2;    /* field를 찾았음 */
     } else {
      workStep = 0;
     }
    } else if (buffer[0] == field[check - strlen(strName) - flag]) {
     check++;
    } else {
     check    = 0;
     workStep = 0;
    }
   }
  } else if (workStep == 2) {
   if (check < strlen(strFileName))   /* filename= 시작위치를 찾는다 */
   {
    if (buffer[0] == strFileName[check])
     check++;
    else
     check = 0;
   } else {
    if (check == strlen(strFileName))
    {
     if (buffer[0] == '\"' || buffer[0] == '\'')
     {
      check++;
      continue;
     }
    }

    if (buffer[0] == '\"' || buffer[0] == '\'' || buffer[0] == '\r' || buffer[0] == ';')
    {
     workStep = 3;

     if (buffer[0] == '\r')    /* g_StrHeaderEnd 늘 찾기위한 시작 */
      check = 1;
     else
      check = 0;
     continue;
    }

    if (strlen(temp) >= (sizeof(temp) - 1))
    {
     LogDebug("JLW_HTTPD_MakeFile() temp buffer overflow error");
     XOAL_F_Close(readFp);
     return JLW_BUFFER_OVERFLOW;
    }

    strcat(temp, (char *)buffer);
   }
  } else {
   if (buffer[0] == g_StrHeaderEnd[check])
    check++;
   else
    check = 0;
   if (check >= strlen(g_StrHeaderEnd))   /* read 시작위치를 찾는다 */
   {
    workStep = 4;
    break;
   }
  }
 }

 if (workStep < 4)
 {
  LogDebug("JLW_HTTPD_MakeFile() filename not found");
  XOAL_F_Close(readFp);
  return JLW_FIELD_NOT_FOUND;
 }

 JLW_ConvPathName(temp);
 if ((posi = strrchr(temp, '\\')))
 {
  if (strlen(posi + 1) >= (fileNameWLen + 1))
  {
   LogDebug("JLW_HTTPD_MakeFile() fileNameW buffer overflow error");
   XOAL_F_Close(readFp);
   return JLW_BUFFER_OVERFLOW;
  }

  strcpy(fileNameW, posi + 1);
 } else {
  if (strlen(temp) >= (fileNameWLen+1))
  {
   LogDebug("JLW_HTTPD_MakeFile() fileNameW buffer overflow error");
   XOAL_F_Close(readFp);
   return JLW_BUFFER_OVERFLOW;
  }

  strcpy(fileNameW, temp);
 }

 JLW_Mkdir(deviceW, pathNameW, FALSE);
#ifndef __NO_VDMS__
 if ((writeFp = XOAL_F_Open(deviceW, pathNameW, fileNameW, DCA_WRITE | DCA_CREATE | DCA_BINARY)) == NULL)
#else
 if ((writeFp = XOAL_F_Open(deviceW, pathNameW, fileNameW, "w+b")) == NULL)
#endif
 {
  LogDebug("JLW_HTTPD_MakeFile() file open error %d:%s/%s", deviceW, pathNameW, fileNameW);
  XOAL_F_Close(readFp);
  return JLW_FILE_OPEN_FAIL;
 }

 check = 0;
 while(!XOAL_F_EOF(readFp))
 {
  if (XOAL_F_Read(readFp, buffer, 1) != 1)
  {
   LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Read error");
   retVal = JLW_BOUNDARY_NOT_FOUND;
   break;
  }

  if (!check)          /* boundary 시작위치를 찾는다 */
  {
   if (buffer[0] == strBoundary[check])
   {
    check++;
   } else {
    if (XOAL_F_Write(writeFp, buffer, 1) != 1)
    {
     LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
     retVal = JLW_FILE_WRITE_FAIL;
     break;
    }
   }
   continue;
  } else if (check < strlen(strBoundary)) {   /* boundary 시작위치를 찾는다 */
   if (buffer[0] == strBoundary[check])
   {
    check++;
    continue;
   } else {
    if (XOAL_F_Write(writeFp, strBoundary, check) != check)
    {
     LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
     retVal = JLW_FILE_WRITE_FAIL;
     break;
    }
   }
  } else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
   if (buffer[0] == boundary[check - strlen(strBoundary)])
   {
    check++;
    continue;
   } else {
    if (XOAL_F_Write(writeFp, strBoundary, strlen(strBoundary)) != strlen(strBoundary))
    {
     LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
     retVal = JLW_FILE_WRITE_FAIL;
     break;
    }
    check -= strlen(strBoundary);
    if (XOAL_F_Write(writeFp, boundary, check) != check)
    {
     LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
     retVal = JLW_FILE_WRITE_FAIL;
     break;
    }
   }
  } else {
   if ((check - strlen(strBoundary) - strlen(boundary)) == 0)
   {
    if (buffer[0] == g_StrCrLf[0])
    {
     check++;
     flag = 0; /* crlf 로 종료 */
     continue;
    } else if (buffer[0] == strRequestEnd[0]) {
     check++;
     flag = 1; /* -- 로 종료 */
     continue;
    }
   } else {
    if ((!flag && buffer[0] == g_StrCrLf[1]) || (flag && buffer[0] == strRequestEnd[1]))
    {
     retVal = JLW_WORK_OK;   /* boundary를 찾음 */
     break;
    }
   }

   if (XOAL_F_Write(writeFp, strBoundary, strlen(strBoundary)) != strlen(strBoundary))
   {
    LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
    retVal = JLW_FILE_WRITE_FAIL;
    break;
   }
   check -= strlen(strBoundary);
   if (XOAL_F_Write(writeFp, boundary, strlen(boundary)) != strlen(boundary))
   {
    LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
    retVal = JLW_FILE_WRITE_FAIL;
    break;
   }
   check -= strlen(boundary);
   if (check)
   {
    if (!flag)
    {
     if (XOAL_F_Write(writeFp, g_StrCrLf, check) != check)
     {
      LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
      retVal = JLW_FILE_WRITE_FAIL;
      break;
     }
    } else {
     if (XOAL_F_Write(writeFp, strRequestEnd, check) != check)
     {
      LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
      retVal = JLW_FILE_WRITE_FAIL;
      break;
     }
    }
   }
  }
  check = 0;
  if (buffer[0] == strBoundary[check])
   check++;
  else {
   if (XOAL_F_Write(writeFp, buffer, 1) != 1)
   {
    LogDebug("JLW_HTTPD_MakeFile() XOAL_F_Write fail");
    retVal = JLW_FILE_WRITE_FAIL;
    break;
   }
  }
 }

 XOAL_F_Close(readFp);
 XOAL_F_Close(writeFp);

 return retVal;
}

/**
 * Function Name : JLW_HTTPD_CopyRequestValue
 *
 * Function Description :
 * Input :
     char *buffer
     int len
 * Output :
     JLW_WorkBuff *retBuff : return buffer data & length
 * Return :  int      : result
*/
static int JLW_HTTPD_CopyRequestValue(U8 *buffer, int len, JLW_WorkBuff *retBuff)
{
 if (retBuff->buff == NULL || (len + strlen((char *)retBuff->buff)) >= retBuff->len)
 {
  U8 *temp;

  temp = retBuff->buff;
  retBuff->len += HTTPD_SMALL_BUFF_SIZE;
  if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(retBuff->len + 1)) == NULL)
  {
   LogDebug("JLW_HTTPD_CopyRequestValue() XOAL_Mem_Malloc fail");
   return JLW_MEMORY_ALLOC_FAIL;
  }
  memset(retBuff->buff, '\0', retBuff->len + 1);
  if (temp) {
   strcpy((char *)retBuff->buff, (char *)temp);
   JLW_XOAL_Mem_Free(temp);
  }
 }

 memcpy((char *)retBuff->buff + strlen((char *)retBuff->buff), buffer, len);
 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_HTTPD_GetFieldFromFile
 *
 * Function Description :
 * Input :
     char *field
     char *boundary
     int deviceR, char *pathNameR, char *fileNameR
 * Output :
     JLW_WorkBuff *retBuff : return buffer data & length
 * Return :  int      : result
*/
int JLW_HTTPD_GetFieldFromFile(char *field, char *boundary, int deviceR, char *pathNameR, char *fileNameR, JLW_WorkBuff *retBuff)
{
 const char  strBoundary[]   = "\r\n--";
 const char  strRequestEnd[] = "--";
 const char  strName[]       = "name=";
 XOF_FILE *readFp;
 U8    buffer[2], *temp;
 int   check, workStep, flag, retVal;

 memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
 if (field == NULL || !strlen(field) || boundary == NULL  || !strlen(boundary)
    || deviceR < 0 || pathNameR == NULL || fileNameR == NULL || !strlen(fileNameR) || retBuff == NULL)
 {
  LogDebug("JLW_HTTPD_GetFieldFromFile() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

#ifndef __NO_VDMS__
 if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, DCA_READ | DCA_BINARY)) == NULL)
#else
 if ((readFp = XOAL_F_Open(deviceR, pathNameR, fileNameR, "rb")) == NULL)
#endif
 {
  LogDebug("JLW_HTTPD_GetFieldFromFile() file open error %d:%s/%s", deviceR, pathNameR, fileNameR);
  return JLW_FILE_OPEN_FAIL;
 }

 memset(buffer, '\0', sizeof(buffer));

 check   = 2;  /* file로 저장된 request는 boundary부터 저장된다 */
 workStep = 0;  /* 0인경우 boundary를 찾음
             1인경우 field를 찾음
             3인경우 read start 위치를 찾음 */
 while(!XOAL_F_EOF(readFp))
 {
  if (XOAL_F_Read(readFp, buffer, 1) != 1)
  {
   LogDebug("JLW_HTTPD_GetFieldFromFile() XOAL_F_Read error");
   XOAL_F_Close(readFp);
   return JLW_FIELD_NOT_FOUND;
  }

  if (!workStep)
  {
   if (!check)           /* boundary 시작위치를 찾는다 */
   {
    if (buffer[0] == strBoundary[check])
     check++;
    continue;
   } else if (check < strlen(strBoundary)) {   /* boundary 시작위치를 찾는다 */
    if (buffer[0] == strBoundary[check])
    {
     check++;
     continue;
    }
   } else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
    if (buffer[0] == boundary[check - strlen(strBoundary)])
    {
     check++;
     continue;
    }
   } else {
    if (buffer[0] == g_StrCrLf[check - strlen(strBoundary) - strlen(boundary)])
    {
     check++;
     if (check >= (strlen(strBoundary) + strlen(boundary) + strlen(g_StrCrLf)))
     {        /* boundary를 찾음 */
      workStep = 1;
      check    = 0;
     }
     continue;
    }
   }
   check = 0;
   if (buffer[0] == strBoundary[check])
    check++;
  } else if (workStep == 1) {
   if (check < strlen(strName))   /* name 시작위치를 찾는다 */
   {
    if (buffer[0] == strName[check])
     check++;
    else
     check = 0;
   } else {
    if (check == strlen(strName))
    {
     if (buffer[0] == '\"' || buffer[0] == '\'')
     {
      flag = 1;
      check++;
      continue;
     } else
      flag = 0;
    }

    if (check == (strlen(strName) + strlen(field) + flag))
    {
     check    = 0;
     if ((flag && (buffer[0] == '\"' || buffer[0] == '\''))
      || (!flag && (buffer[0] == '\r' || buffer[0] == ';')))
     {
      workStep = 2;    /* field를 찾았음 */

      if (buffer[0] == '\r')  /* g_StrHeaderEnd 늘 찾기위한 시작 */
       check = 1;
      else
       check = 0;
     } else {
      workStep = 0;
     }
    } else if (buffer[0] == field[check - strlen(strName) - flag]) {
     check++;
    } else {
     check    = 0;
     workStep = 0;
    }
   }
  } else {
   if (buffer[0] == g_StrHeaderEnd[check])
    check++;
   else
    check = 0;
   if (check >= strlen(g_StrHeaderEnd))   /* read 시작위치를 찾는다 */
   {
    workStep = 3;
    break;
   }
  }
 }

 if (workStep < 3)
 {
  LogDebug("JLW_HTTPD_GetFieldFromFile() filename not found");
  XOAL_F_Close(readFp);
  return JLW_FIELD_NOT_FOUND;
 }

 check = 0;
 while(!XOAL_F_EOF(readFp))
 {
  if (XOAL_F_Read(readFp, buffer, 1) != 1)
  {
   LogDebug("JLW_HTTPD_GetFieldFromFile() XOAL_F_Read error");
   retVal = JLW_BOUNDARY_NOT_FOUND;
   break;
  }

  if (!check)           /* boundary 시작위치를 찾는다 */
  {
   if (buffer[0] == strBoundary[check])
    check++;
   else {
    if ((retVal = JLW_HTTPD_CopyRequestValue(buffer, 1, retBuff)))
     break;
   }
   continue;
  } else if (check < strlen(strBoundary)) {   /* boundary 시작위치를 찾는다 */
   if (buffer[0] == strBoundary[check])
   {
    check++;
    continue;
   } else {
    if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, check, retBuff)))
     break;
   }
  } else if (check < (strlen(strBoundary) + strlen(boundary))) { /* boundary인지 비교해본다 */
   if (buffer[0] == boundary[check - strlen(strBoundary)])
   {
    check++;
    continue;
   } else {
    if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, strlen(strBoundary), retBuff)))
     break;
    check -= strlen(strBoundary);
    if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)boundary, check, retBuff)))
     break;
   }
  } else {
   if ((check - strlen(strBoundary) - strlen(boundary)) == 0)
   {
    if (buffer[0] == g_StrCrLf[0])
    {
     check++;
     flag = 0; /* crlf 로 종료 */
     continue;
    } else if (buffer[0] == strRequestEnd[0]) {
     check++;
     flag = 1; /* -- 로 종료 */
     continue;
    }
   } else {
    if ((!flag && buffer[0] == g_StrCrLf[1]) || (flag && buffer[0] == strRequestEnd[1]))
    {
     retVal = JLW_WORK_OK;   /* boundary를 찾음 */
     break;
    }
   }

   if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strBoundary, strlen(strBoundary), retBuff)))
    break;
   check -= strlen(strBoundary);
   if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)boundary, strlen(boundary), retBuff)))
    break;
   check -= strlen(boundary);
   if (check)
   {
    if (!flag)
    {
     if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)g_StrCrLf, check, retBuff)))
      break;
    } else {
     if ((retVal = JLW_HTTPD_CopyRequestValue((U8 *)strRequestEnd, check, retBuff)))
      break;
    }
   }
  }
  check = 0;
  if (buffer[0] == strBoundary[check])
   check++;
  else {
   if ((retVal = JLW_HTTPD_CopyRequestValue(buffer, 1, retBuff)))
    break;
  }
 }

 XOAL_F_Close(readFp);

 if (retVal)
 {
  JLW_XOAL_Mem_Free(retBuff->buff);
  memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
 }

 return retVal;
}

static const JLW_MimeType s_mimeType[] = {
#if 0
 { "abs",   "audio/x-mpeg" },
 { "ai",   "application/postscript" },
 { "aif",   "audio/x-aiff" },
 { "aifc",   "audio/x-aiff" },
 { "aiff",   "audio/x-aiff" },
 { "aim",   "application/x-aim" },
#endif
 { "art",   "image/x-jg" },
#if 0
 { "asf",   "video/x-ms-asf" },
 { "asx",   "video/x-ms-asf" },
 { "au",   "audio/basic" },
 { "avi",   "video/x-msvideo" },
 { "avx",   "video/x-rad-screenplay" },
 { "bcpio",  "application/x-bcpio" },
 { "bin",   "application/octet-stream" },
#endif
 { "bmp",   "image/bmp" },
 { "body",   "text/html" },
#if 0
 { "cdf",   "application/x-cdf" },
 { "cer",   "application/x-x509-ca-cert" },
 { "class",  "application/java" },
 { "cpio",   "application/x-cpio" },
 { "csh",   "application/x-csh" },
#endif
 { "css",   "text/css" },
 { "dib",   "image/bmp" },
#if 0
 { "doc",   "application/msword" },
 { "dtd",   "application/xml-dtd" },
 { "dv",   "video/x-dv" },
 { "dvi",   "application/x-dvi" },
 { "eps",   "application/postscript" },
#endif
 { "etx",   "text/x-setext" },
 { "exe",   "application/octet-stream" },
 { "gif",   "image/gif" },
#if 0
 { "gtar",   "application/x-gtar" },
 { "gz",   "application/x-gzip" },
 { "hdf",   "application/x-hdf" },
 { "hqx",   "application/mac-binhex40" },
#endif
 { "htc",   "text/x-component" },
 { "htm",   "text/html" },
 { "html",   "text/html" },
#if 0
 { "hqx",   "application/mac-binhex40" },
#endif
 { "ief",   "image/ief" },
 { "jad",   "text/vnd.sun.j2me.app-descriptor" },
#if 0
 { "jar",   "application/java-archive" },
#endif
 { "java",   "text/plain" },
#if 0
 { "jnlp",   "application/x-java-jnlp-file" },
#endif
 { "jpe",   "image/jpeg" },
 { "jpeg",   "image/jpeg" },
 { "jpg",   "image/jpeg" },
 { "js",   "text/javascript" },
 { "jsf",   "text/plain" },
 { "jspf",   "text/plain" },
#if 0
 { "kar",   "audio/x-midi" },
 { "latex",  "application/x-latex" },
 { "m3u",   "audio/x-mpegurl" },
#endif
 { "mac",   "image/x-macpaint" },
#if 0
 { "man",   "application/x-troff-man" },
 { "mathml",  "application/mathml+xml" },
 { "me",   "application/x-troff-me" },
 { "mid",   "audio/x-midi" },
 { "midi",   "audio/x-midi" },
 { "mif",   "application/x-mif" },
 { "mov",   "video/quicktime" },
 { "movie",  "video/x-sgi-movie" },
 { "mp1",   "audio/x-mpeg" },
 { "mp2",   "audio/x-mpeg" },
 { "mp3",   "audio/x-mpeg" },
 { "mp4",   "video/mp4" },
 { "mpa",   "audio/x-mpeg" },
 { "mpe",   "video/mpeg" },
 { "mpeg",   "video/mpeg" },
 { "mpega",  "audio/x-mpeg" },
 { "mpg",   "video/mpeg" },
 { "mpv2",   "video/mpeg2" },
 { "ms",   "application/x-wais-source" },
 { "nc",   "application/x-netcdf" },
 { "oda",   "application/oda" },
 { "ogg",   "application/ogg" },
#endif
 { "pbm",   "image/x-portable-bitmap" },
 { "pct",   "image/pict" },
 { "pdf",   "application/pdf" },
 { "pgm",   "image/x-portable-graymap" },
 { "pic",   "image/pict" },
 { "pict",   "image/pict" },
#if 0
 { "pls",   "audio/x-scpls" },
#endif
 { "png",   "image/png" },
 { "pnm",   "image/x-portable-anymap" },
 { "pnt",   "image/x-macpaint" },
 { "ppm",   "image/x-portable-pixmap" },
#if 0
 { "ppt",   "application/powerpoint" },
 { "ps",   "application/postscript" },
#endif
 { "psd",   "image/x-photoshop" },
#if 0
 { "qt",   "video/quicktime" },
#endif
 { "qti",   "image/x-quicktime" },
 { "qtif",   "image/x-quicktime" },
 { "ras",   "image/x-cmu-raster" },
#if 0
 { "rdf",   "application/rdf+xml" },
#endif
 { "rgb",   "image/x-rgb" },
#if 0
 { "rm",   "application/vnd.rn-realmedia" },
 { "roff",   "application/x-troff" },
 { "rtf",   "application/rtf" },
#endif
 { "rtx",   "text/richtext" },
#if 0
 { "sh",   "application/x-sh" },
 { "shar",   "application/x-shar" },
 { "smf",   "audio/x-midi" },
 { "sit",   "application/x-stuffit" },
 { "snd",   "audio/basic" },
 { "src",   "application/x-wais-source" },
 { "sv4cpio",  "application/x-sv4cpio" },
 { "sv4crc",  "application/x-sv4crc" },
 { "swf",   "application/x-shockwave-flash" },
 { "t",   "application/x-troff" },
 { "tar",   "application/x-tar" },
 { "tcl",   "application/x-tcl" },
 { "tex",   "application/x-tex" },
 { "texi",   "application/x-texinfo" },
 { "texinfo",  "application/x-texinfo" },
#endif
 { "tif",   "image/tiff" },
 { "tiff",   "image/tiff" },
#if 0
 { "tr",   "application/x-troff" },
#endif
 { "tsv",   "text/tab-separated-values" },
 { "txt",   "text/plain" },
#if 0
 { "ulw",   "audio/basic" },
 { "ustar",  "application/x-ustar" },
 { "vxml",   "application/voicexml+xml" },
#endif
 { "xbm",   "image/x-xbitmap" },
 { "xht",   "application/xhtml+xml" },
 { "xhtml",  "application/xhtml+xml" },
 { "xml",   "application/xml" },
 { "xpm",   "image/x-xpixmap" },
 { "xsl",   "application/xml" },
 { "xslt",   "application/xslt+xml" },
 { "xul",   "application/vnd.mozilla.xul+xml" },
 { "xwd",   "image/x-xwindowdump" },
#if 0
 { "wav",   "audio/x-wav" },
#endif
 { "svg",   "image/svg+xml" },
 { "svgz",   "image/svg+xml" },
#if 0
 { "vsd",   "application/x-visio" },
#endif
 { "wbmp",   "image/vnd.wap.wbmp" },
 { "wml",   "text/vnd.wap.wml" },
#if 0
 { "wmlc",   "application/vnd.wap.wmlc" },
#endif
 { "wmls",   "text/vnd.wap.wmlscript" },
#if 0
 { "wmlscriptc", "application/vnd.wap.wmlscriptc" },
 { "wmv",   "video/x-ms-wmv" },
 { "wrl",   "x-world/x-vrml" },
 { "wspolicy",  "application/wspolicy+xml" },
 { "Z",   "application/x-compress" },
 { "z",   "application/x-compress" },
 { "zip",   "application/zip" },
#endif
 { "xls",   "application/vnd.ms-excel" },
 { "doc",   "application/vnd.ms-word" },
 { "ppt",   "application/vnd.ms-powerpoint" },
 {   NULL,    NULL }
};

/**
 * Function Name : JLW_GetMimeType
 *
 * Function Description : Mime type return
 * Input :
 * Output :
      char *ext
 * Return :   char *    : return mime type
*/
char *JLW_GetMimeType(char *ext)
{
 int i;

 for (i = 0; s_mimeType[i].ext[0] != '\0'; i++)
 {
  if (!strcmp(s_mimeType[i].ext, ext))
   return (char *)s_mimeType[i].type;
 }

 return NULL;
}

/**
 * Function Name : JLW_MKDir
 *
 * Function Description :
 * Input :
 * Output :
      S32 nDevice
      char *pathName
      bool fileInFlag
 * Return :   int    : result
*/
int JLW_Mkdir(S32 nDevice, char *pathName, bool fileInFlag)
{
 char *filePosi = NULL, *posi, *next;
 int  len;

 if (fileInFlag)
 {
  if ((filePosi = strrchr(posi, '\\')))
  {
   *filePosi = '\0';
  } else {
   return JLW_WORK_OK;
  }
 }
 posi = pathName + strlen(pathName) - 1;
 if (*posi == '\\')
  *posi == '\0';
 else


 posi = pathName;
 while ((next = strchr(posi, '\\')))
 {
  *next = '\0';
  XOAL_F_MkDir(nDevice, pathName);
  *next = '\\';
  posi = next + 1;
 }
 XOAL_F_MkDir(nDevice, pathName);

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_Rmdir
 *
 * Function Description :
 * Input :
 * Output :
      S32 nDevice
      char *pathName
      bool fileInFlag
 * Return :   int    : result
*/
int JLW_Rmdir(S32 nDevice, char *pathName, bool fileInFlag)
{
 char *filePosi = NULL, *posi;

 if (fileInFlag)
 {
  if ((filePosi = strrchr(posi, '\\')))
  {
   *filePosi = '\0';
  } else {
   return JLW_WORK_OK;
  }
 }
 posi = pathName + strlen(pathName) - 1;
 if (*posi == '\\')
  *posi == '\0';
 else
  posi = NULL;

 XOAL_F_RmDir(nDevice, pathName);

 if (posi)
  *posi = '\\';

 if (filePosi)
  *filePosi = '\\';

 return JLW_WORK_OK;
}

/**
 * Function Name : JLW_Makedir
 *
 * Function Description :
 * Input :
      char *basePathName
      char *makePathName
 * Output :
      char *retPathName
 * Return :
*/
void JLW_Makedir(char *basePathName, char *makePathName, char *retPathName)
{
 char *posi, *next;
 int  len;

 retPathName[0] = '\0';

 if (basePathName == NULL)
  basePathName = "";
 if (makePathName == NULL)
  makePathName = "";

 len = strlen(basePathName) + strlen(makePathName);
 if (!len)
  return;

 if (strlen(basePathName))
 {
  if (*makePathName == '/' || *makePathName == '\\')
   next = makePathName+1;
  else
   next = makePathName;

  posi = basePathName + strlen(basePathName) - 1;
  if (*posi == '/' || *posi == '\\')
   sprintf(retPathName, "%s%s",   basePathName, next);
  else
   sprintf(retPathName, "%s\\%s", basePathName, next);
 } else {
  strcpy(retPathName, makePathName);
 }

 JLW_ConvPathName(retPathName);
}

/**
 * Function Name : JLW_ConvPathName
 *
 * Function Description :
 * Input :
 * Output :
      char *pathName
 * Return :
*/
void JLW_ConvPathName(char *pathName)
{
 char *posi;

 if (pathName == NULL)
  return;

 posi = pathName;
 while ((posi = strchr(posi, '/')))
 {
  *posi = '\\';
  posi++;
 }
}
----------------------------------------------------------------
Error message send functions
----------------------------------------------------------------

    const char g_strHttpStatus200[] = "200 OK";
static const char s_strHttpStatus301[] = "301 Moved Permanently";
static const char s_strHttpStatus302[] = "302 Moved Temporarily";
static const char s_strHttpStatus304[] = "304 Not Modified";
static const char s_strHttpStatus400[] = "400 Bad Request";
static const char s_strHttpStatus401[] = "401 Unauthorized";
static const char s_strHttpStatus403[] = "403 Forbidden";
static const char s_strHttpStatus404[] = "404 Not Found";
static const char s_strHttpStatus411[] = "411 Length Required";
static const char s_strHttpStatus412[] = "412 Precondition Failed";
static const char s_strHttpStatus414[] = "414 Request URI Too Long";
static const char s_strHttpStatus416[] = "416 Invalid Range";
static const char s_strHttpStatus500[] = "500 Server Error";
static const char s_strHttpStatus501[] = "501 Not Implemented";
static const char s_strHttpStatus502[] = "502 Bad Gateway";
static const char s_strHttpStatus503[] = "503 Service Unavailable";
static const char s_strHttpStatus505[] = "505 HTTP Version Not Supported";

static const char s_bodyFormat301[] =
    "<HTML><HEAD><TITLE>301 Moved Permanently</TITLE></HEAD>\r\n"
    "<BODY><H1>301 Moved</H1>The document has moved\r\n"
    "<A HREF=\"%s\">here</A>.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat302[] =
    "<HTML><HEAD><TITLE>302 Moved Temporarily</TITLE></HEAD>\r\n"
    "<BODY><H1>302 Moved</H1>The document has moved\r\n"
    "<A HREF=\"%s\">here</A>.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat304[] = "\r\n";
static const char s_bodyFormat400[] =
    "<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\r\n"
    "<BODY><H1>400 Bad Request</H1>Your client has issued a malformed or illegal request.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat401[] =
    "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\r\n"
    "<BODY><H1>401 Unauthorized</H1>Your client does not have permission to get URL %s from this server.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat403[] =
    "<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\r\n"
    "<BODY><H1>403 Forbidden</H1>Your client does not have permission to get URL %s from this server.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat404[] =
//  "<html><head><title>JLW-HttpdServer - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body>"
//  "<h1>HTTP Status 404 - %s</h1><HR size=\"1\" noshade=\"noshade\"><p><b>type</b> Status report</p><p><b>message</b> <u>%s</u></p><p><b>description</b> <u>The requested resource (%s) is not available.</u></p><HR size=\"1\" noshade=\"noshade\"><h3>JLW-HttpdServer</h3></body></html>\r\n";
    "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\r\n"
    "<BODY><H1>404 Not Found</H1>The requested URL %s was not found on this server.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat411[] =
    "<HTML><HEAD><TITLE>411 Length Required</TITLE></HEAD>\r\n"
    "<BODY><H1>411 Length Required</H1>The requested URL %s requires that a valid Content-Length header be sent with it.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat412[] =
    "<HTML><HEAD><TITLE>412 Precondition Failed</TITLE></HEAD>\r\n"
    "<BODY><H1>412 Precondition Failed</H1></BODY></HTML>\r\n";
static const char s_bodyFormat414[] =
    "<HTML><HEAD><TITLE>414 Request URI Too Long</TITLE></HEAD>\r\n"
    "<BODY><H1>414 Request URI Too Long</H1>Your client has issued a malformed or illegal request.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat416[] =
    "<HTML><HEAD><TITLE>416 Invalid Range</TITLE></HEAD>\r\n"
    "<BODY><H1>416 Invalid Range</H1></BODY></HTML>\r\n";
static const char s_bodyFormat500[] =
    "<HTML><HEAD><TITLE>500 Server Error</TITLE></HEAD>\r\n"
    "<BODY><H1>500 Server Error</H1>The server encountered an internal error and could not complete your request.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat501[] =
    "<HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD>\r\n"
    "<BODY><H1>501 Not Implemented</H1>POST to non-script is not supported\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat502[] =
    "<HTML><HEAD><TITLE>502 Bad Gateway</TITLE></HEAD>\r\n"
    "<BODY><H1>502 Bad Gateway</H1>The CGI was not CGI/1.1 compliant.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat503[] =
    "<HTML><HEAD><TITLE>503 Service Unavailable</TITLE></HEAD>\r\n"
    "<BODY><H1>503 Service Unavailable</H1>There are too many connections in use right now.\r\n"
    "Please try again later.\r\n"
    "</BODY></HTML>\r\n";
static const char s_bodyFormat505[] =
    "<HTML><HEAD><TITLE>505 HTTP Version Not Supported</TITLE></HEAD>\r\n"
    "<BODY><H1>505 HTTP Version Not Supported</H1>POST to non-script is not supported"
    "</BODY></HTML>\r\n";

#if 0
static const char s_bodyFormat200[] =
    "<HTML><HEAD><TITLE>JLW Server Test</TITLE></HEAD>\r\n"
    "<BODY><H1>HTTP 200 OK test</H1>Hello world"
    "</BODY></HTML>\r\n";
#endif
static const JLW_ErrorInfo s_getUrlInfo[] = {
// { FALSE, 200, (char *)g_strHttpStatus200, (char *)s_bodyFormat200 },
 { TRUE,  301, (char *)s_strHttpStatus301, (char *)s_bodyFormat301 },
 { TRUE,  302, (char *)s_strHttpStatus302, (char *)s_bodyFormat302 },
 { FALSE, 304, (char *)s_strHttpStatus304, (char *)s_bodyFormat304 },
 { FALSE, 400, (char *)s_strHttpStatus400, (char *)s_bodyFormat400 },
 { TRUE,  401, (char *)s_strHttpStatus401, (char *)s_bodyFormat401 },
 { TRUE,  403, (char *)s_strHttpStatus403, (char *)s_bodyFormat403 },
 { TRUE,  404, (char *)s_strHttpStatus404, (char *)s_bodyFormat404 },
 { TRUE,  411, (char *)s_strHttpStatus411, (char *)s_bodyFormat411 },
 { FALSE, 412, (char *)s_strHttpStatus412, (char *)s_bodyFormat412 },
 { FALSE, 414, (char *)s_strHttpStatus414, (char *)s_bodyFormat414 },
 { FALSE, 416, (char *)s_strHttpStatus416, (char *)s_bodyFormat416 },
 { FALSE, 500, (char *)s_strHttpStatus500, (char *)s_bodyFormat500 },
 { FALSE, 501, (char *)s_strHttpStatus501, (char *)s_bodyFormat501 },
 { FALSE, 502, (char *)s_strHttpStatus502, (char *)s_bodyFormat502 },
 { FALSE, 503, (char *)s_strHttpStatus503, (char *)s_bodyFormat503 },
 { FALSE, 505, (char *)s_strHttpStatus505, (char *)s_bodyFormat505 },
 { FALSE, 0, NULL, NULL }
};
/**
 * Function Name : JLW_HTTPD_SendHttpdError
 *
 * Function Description :
 * Input :
     XONS_SOCKET sock
     int httpStatus
     U8 *url
 * Output :
 * Return :  int      : result
*/
int JLW_HTTPD_SendHttpdError(XONS_SOCKET sock, JLW_HttpdServerInfo *servInfo, int httpStatus, char *url)
{
 JLW_WorkBuff headBuff, bodyBuff;
 int    retVal, i;

 if (sock < 0 || servInfo == NULL || httpStatus < 0)
 {
  LogDebug("JLW_HTTPD_SendHttpdError() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 for (i = 0; ; i++)
 {
  if (!s_getUrlInfo[i].httpStatus)
   return JLW_WORK_FAIL;
  if (s_getUrlInfo[i].httpStatus == httpStatus)
   break;
 }

 if (s_getUrlInfo[i].freeCheck)
 {
  if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_getUrlInfo[i].bodyFormat, url, &bodyBuff)))
   return retVal;
 } else {
  bodyBuff.buff = (U8 *)s_getUrlInfo[i].bodyFormat;
  bodyBuff.len  = strlen(s_getUrlInfo[i].bodyFormat);
 }

 if ((retVal = JLW_HTTPD_MakeHttpdHeader(s_getUrlInfo[i].strHttpStatus, bodyBuff.len, &headBuff)))
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }

 retVal = JLW_HttpdSendBasic(sock, &headBuff, &bodyBuff, servInfo->sendTime);

 if (s_getUrlInfo[i].freeCheck)
  JLW_XOAL_Mem_Free(bodyBuff.buff);
 JLW_XOAL_Mem_Free(headBuff.buff);
 if (!JLW_Httpd_Recv(sock, &headBuff, 100, NULL))
  JLW_XOAL_Mem_Free(headBuff.buff);

 return retVal;
#if 0
 JLW_WorkBuff headBuff, bodyBuff;
 int    retVal;
 const char  *strHttpStatus;
 bool   freeCheck = FALSE;

 if (sock < 0 || httpStatus < 0)
 {
  LogDebug("JLW_HTTPD_SendHttpdError() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 switch (httpStatus)
 {
  case 301 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat301, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus301;
   break;
  case 302 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat302, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus302;
   break;
  case 304 :
   memset((char *)&bodyBuff, '\0', sizeof(JLW_WorkBuff));
   strHttpStatus = s_strHttpStatus304;
   break;
  case 400 :
   bodyBuff.buff = (U8 *)s_bodyFormat400;
   bodyBuff.len  = strlen(s_bodyFormat400);
   strHttpStatus = s_strHttpStatus400;
   break;
  case 401 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat401, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus401;
   break;
  case 403 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat403, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus403;
   break;
  case 404 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat404, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus404;
   break;
  case 411 :
   freeCheck = TRUE;
   if ((retVal = JLW_HTTPD_MakeHttpdErrorBody(s_bodyFormat411, url, &bodyBuff)))
    return retVal;
   strHttpStatus = s_strHttpStatus411;
   break;
  case 412 :
   bodyBuff.buff = (U8 *)s_bodyFormat412;
   bodyBuff.len  = strlen(s_bodyFormat412);
   strHttpStatus = s_strHttpStatus412;
   break;
  case 414 :
   bodyBuff.buff = (U8 *)s_bodyFormat414;
   bodyBuff.len  = strlen(s_bodyFormat414);
   strHttpStatus = s_strHttpStatus414;
   break;
  case 416 :
   bodyBuff.buff = (U8 *)s_bodyFormat416;
   bodyBuff.len  = strlen(s_bodyFormat416);
   strHttpStatus = s_strHttpStatus416;
   break;
  case 500 :
   bodyBuff.buff = (U8 *)s_bodyFormat500;
   bodyBuff.len  = strlen(s_bodyFormat500);
   strHttpStatus = s_strHttpStatus500;
   break;
  case 501 :
   bodyBuff.buff = (U8 *)s_bodyFormat501;
   bodyBuff.len  = strlen(s_bodyFormat501);
   strHttpStatus = s_strHttpStatus501;
   break;
  case 502 :
   bodyBuff.buff = (U8 *)s_bodyFormat502;
   bodyBuff.len  = strlen(s_bodyFormat502);
   strHttpStatus = s_strHttpStatus502;
   break;
  case 503 :
   bodyBuff.buff = (U8 *)s_bodyFormat503;
   bodyBuff.len  = strlen(s_bodyFormat503);
   strHttpStatus = s_strHttpStatus503;
   break;
  case 505 :
   bodyBuff.buff = (U8 *)s_bodyFormat505;
   bodyBuff.len  = strlen(s_bodyFormat505);
   strHttpStatus = s_strHttpStatus505;
   break;
 }

 if ((retVal = JLW_HTTPD_MakeHttpdHeader(strHttpStatus, bodyBuff.len, &headBuff)))
 {
  JLW_XOAL_Mem_Free(bodyBuff.buff);
  return retVal;
 }

 retVal = JLW_HttpdSendBasic(sock, &headBuff, &bodyBuff, servInfo->sendTime);

 if (freeCheck)
  JLW_XOAL_Mem_Free(bodyBuff.buff);
 JLW_XOAL_Mem_Free(headBuff.buff);

 return retVal;
#endif
}

/**
 * Function Name : JLW_HTTPD_MakeHttpdErrorBody
 *
 * Function Description :
 * Input :
     char *bodyFormat
     U8 *url
 * Output :
     JLW_WorkBuff *retBuff : return buffer data & length
 * Return :  int      : result
*/
int JLW_HTTPD_MakeHttpdErrorBody(const char *bodyFormat, char *url, JLW_WorkBuff *retBuff)
{
 U32  len;

 memset((char *)retBuff, '\0', sizeof(JLW_WorkBuff));
 if (bodyFormat == NULL || !strlen(bodyFormat) || url == NULL || !strlen(url))
 {
  LogDebug("JLW_HTTPD_MakeHttpdErrorBody() function call data error");
  return JLW_CALL_DATA_FAIL;
 }

 len = strlen(bodyFormat) + strlen(url) - 1 * 2;
 if ((retBuff->buff = (U8 *)XOAL_Mem_Malloc(len + 1)) == NULL)
 {
  LogDebug("JLW_HTTPD_MakeHttpdErrorBody() XOAL_Mem_Malloc fail");
  return JLW_MEMORY_ALLOC_FAIL;
 }

 retBuff->len = len;
 memset(retBuff->buff, '\0', len + 1);
 sprintf((char *)retBuff->buff, bodyFormat, url);

#if 0
 {
  U8  temp[101];
  int  i;

  LogDebug("JLW_HTTPD_MakeHttpdErrorBody() len=%d", len);
  for (i = 0; i < len; i+= 100)
  {
   strncpy(temp, retBuff->buff+i, 100);
   LogDebug("%s", temp);
  }
 }
#endif

 return JLW_WORK_OK;
}

+ Recent posts