/* IglooFTP - Graphical and User Friendly FTP Client.
 * Copyright (c) 1998-1999 Jean-Marc Jacquet. 
 * All rights reserved.
 * 
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE
 *
 * IglooFTP Original Packages, information and support,  
 * can be obtained at :
 *                              http://www.littleigloo.org
 * 
 *
 */


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <locale.h>
#include <errno.h>

#include "protos.h"


#define FTP_error_msg(x) error_message(x)






static int
FTP_misc_error (int error_code, char *msg, char *msg_operand)
{
  char error_msg[255];
  sprintf (error_msg, "%s%s %s", msg, msg_operand, strerror (errno));
  FTP_error_msg (error_msg);
  return error_code;
}


static int
FTP_what_month (char *month)
{
  switch (month[0])
    {
    case 'J':
      if (toupper (month[1]) == 'A')
	return 1;
      if (toupper (month[2]) == 'N')
	return 6;
      return 7;
    case 'F':
      return 2;
    case 'M':
      if (toupper (month[2]) == 'R')
	return 3;
      return 5;
    case 'A':
      if (toupper (month[2]) == 'R')
	return 4;
      return 8;
    case 'S':
      return 9;
    case 'O':
      return 10;
    case 'N':
      return 11;
    case 'D':
      return 12;
    default:
      return 1;
    }
  return 1;
}





char
FTP_format_dir_list (char *inputfile, char *outputfile, char host_type)
{
  FILE *in;
  FILE *out;
  FTPfileinfo this_file;
  char this_line[255];
  char line_buf[255];
  register char *ptr;
  char *ptr1 = NULL;
  char *ptr2 = NULL;
  time_t timep;
  struct tm *file_date;
  int this_year;
  char this_month, this_day;
  char is_it_a_linked_dir = FALSE;



  FTP_MISC_DEBUG ("FTPmisc : FTP_format_dir_list BEGIN");


  /* host_type=HOST_WIN_NT; */
  /* if (!(in = fopen ("/tmp/win_nt.dir", "r"))) */

  if (!(in = fopen (inputfile, "r")))
    return FTP_misc_error (FALSE, "LOCAL (FTP_format_dir_list) error opening for reading : ", inputfile);

  if (!(out = fopen (outputfile, "w+")))
    return FTP_misc_error (FALSE, "LOCAL  (FTP_format_dir_list) error opening for writing : ", outputfile);


  setlocale (LC_ALL, "");
  timep = time (NULL);
  file_date = localtime (&timep);
  this_year = file_date->tm_year;
  this_month = file_date->tm_mon;
  this_day = file_date->tm_mday;

  switch (host_type)
    {

    case HOST_WIN_NT:
      while (fgets (this_line, sizeof (this_line), in))
	{
	  FTP_MISC_DEBUG (this_line);

	  if ((ptr = strchr (this_line, '\r')))
	    *ptr = 0;
	  else if ((ptr = strchr (this_line, '\n')))
	    *ptr = 0;

	  if (!strlen (this_line))
	    continue;

	  if (!isdigit (this_line[0]))	/* UNIX ls */
	    {
	      fseek (in, 0L, SEEK_SET);
	      fseek (out, 0L, SEEK_SET);
	      goto host_unix;
	    }

	  memset (&this_file, 0, sizeof (this_file));
	  strcpy (this_file.attrib, "----------");

	  strcpy (this_file.gid, "unknown");
	  strcpy (this_file.uid, "unknown");

	  strncpy (line_buf, this_line, 2);
	  file_date->tm_mon = atoi (line_buf) - 1;

	  strncpy (line_buf, (char *) this_line + 3, 2);
	  file_date->tm_mday = atoi (line_buf);

	  strncpy (line_buf, (char *) this_line + 6, 2);
	  file_date->tm_year = atoi (line_buf) > 70 ? atoi (line_buf) : atoi (line_buf) + 100;

	  ptr = strchr (this_line, 'M') + 2;
	  while (*(++ptr) == 32);


	  if (*ptr == '<')
	    {
	      this_file.attrib[0] = 'd';
	      ptr += 5;
	      strcpy (this_file.size, "0");
	    }
	  else
	    {
	      ptr1 = ptr;
	      while (isdigit (*(++ptr)));
	      *ptr = 0;
	      strcpy (this_file.size, ptr1);
	    }

	  while (*(++ptr) == 32);

	  strcpy (this_file.name, ptr);

	  if (this_file.attrib[0] == 'd')
	    if (this_file.name[0] == '.')
	      if (this_file.name[1] == 0 || this_file.name[1] == '.')
		continue;


	  strftime (this_file.date, sizeof (this_file.date), FTP_REMOTE_DATE_FORMAT, file_date);
	  this_file.date[0] = toupper (this_file.date[0]);
	  FTP_MISC_DEBUG_LOG_THIS_LINE ();

	  fwrite (&this_file, sizeof (this_file), 1, out);
	}
      break;

    case HOST_SUNOS:
    case HOST_UNIX:
    default:
    host_unix:
      while (fgets (this_line, sizeof (this_line), in))
	{
	  FTP_MISC_DEBUG (this_line);

	  if (!strncmp (this_line, "total ", 6))
	    continue;

	  if ((ptr = strchr (this_line, '\r')))
	    *ptr = 0;
	  else if ((ptr = strchr (this_line, '\n')))
	    *ptr = 0;

	  if (!strlen (this_line))
	    continue;

	  if (this_line[0] == '.')
	    continue;

	  memset (&this_file, 0, sizeof (this_file));

	  is_it_a_linked_dir = FALSE;
	  if ((ptr = strstr (this_line, "->")))
	    {
	      char *this_link = (char *) ptr + 3;
	      char *THIS_LINK = g_strdup (this_link);
	      char *filenames[] =
	      {"READMEWELCOMEMESSAGE"};
	      const char dot = '.';

	      strupr (THIS_LINK);
	      is_it_a_linked_dir = (this_line[strlen (this_line) - 1] == '/')
		|| (!strcmp (this_link, "."))
		|| ((!strncmp (this_link, "..", 2) && strrchr (this_link + 2, dot) == NULL))
		|| (strchr (this_link, dot) == NULL && strstr (filenames[0], this_link) == NULL);
	      g_free (THIS_LINK);

	      *(--ptr) = 0;
	    }

	  strncpy (this_file.attrib, this_line, 10);

	  if (is_it_a_linked_dir)
	    this_file.attrib[0] = 'D';

	  if ((ptr = strchr (this_line, 32)) == NULL)
	    continue;

	  while (*(++ptr) == 32);
	  while (*(++ptr) != 32);
	  while (*(++ptr) == 32);

	  /* uid */
	  ptr1 = ptr;
	  while (*(++ptr1) != 32);
	  *ptr1 = 0;
	  strcpy (this_file.uid, ptr);

	  /* gid */
	  ptr = ptr1;
	  while (*(++ptr) == 32);
	  ptr1 = ptr;
	  while (*(++ptr1) != 32);
	  *ptr1 = 0;
	  strcpy (this_file.gid, ptr);

	  /* size */
	  ptr = ptr1;
	  while (*(++ptr) == 32);
	  ptr1 = ptr;
	  while (*(++ptr1) != 32);
	  *ptr1 = 0;
	  strcpy (this_file.size, ptr);

	  /* month */
	  ptr = ptr1;
	  while (*(++ptr) == 32);
	  *(ptr1 = ptr + 3) = 0;
	  file_date->tm_mon = FTP_what_month (ptr) - 1;

	  /* day */
	  ptr = ptr1 + 1;
	  *(ptr1 = ptr + 2) = 0;
	  file_date->tm_mday = atoi (ptr);


	  /* year */
	  ptr = ptr1 + 1;
	  *(ptr1 = ptr + 5) = 0;
	  file_date->tm_year = (*ptr == 32) ? atoi (ptr + 1) - 1900 : this_year;

	  if (file_date->tm_year == this_year)
	    if ((file_date->tm_mon > this_month) || ((file_date->tm_mon == this_month) && (file_date->tm_mday > this_day)))
	      file_date->tm_year--;

	  /* name */
	  strcpy (this_file.name, ++ptr1);
	  /* -- "." or ".." not processed -- */
	  if (this_file.name[0] == '.')
	    if (this_file.name[1] == 0 || this_file.name[1] == '.')
	      continue;



	  strftime (this_file.date, sizeof (this_file.date), FTP_REMOTE_DATE_FORMAT, file_date);
	  this_file.date[0] = toupper (this_file.date[0]);

	  FTP_MISC_DEBUG_LOG_THIS_LINE ();

	  fwrite (&this_file, sizeof (this_file), 1, out);
	}
      break;


    case HOST_VMS:
      while (fgets (this_line, sizeof (this_line), in))
	{
	  memset (&this_file, 0, sizeof (this_file));
	  strcpy (this_file.attrib, "----------");

	  FTP_MISC_DEBUG (this_line);

	  if (!strncmp (this_line, "Total of ", 8))
	    continue;

	  if ((ptr = strchr (this_line, '\r')))
	    *ptr = 0;
	  else if ((ptr = strchr (this_line, '\n')))
	    *ptr = 0;

	  if (!strlen (this_line))
	    continue;

	  if ((ptr1 = strchr (this_line, ';')) == NULL)
	    continue;

	  *ptr1 = 0;
	  strcpy (this_file.name, this_line);
	  *ptr1 = ';';

	  if ((ptr = strstr (this_file.name, ".DIR")))
	    {
	      this_file.attrib[0] = 'd';
	      *ptr = 0;
	    }

	  while (isdigit (*(++ptr1)));

	  if ((ptr2 = strchr (ptr1, ':')) == NULL)
	    continue;

	  ptr2 += 3;
	  *(ptr2 - 6) = 0;
	  ptr = ptr2 - 10;

	  file_date->tm_year = atoi (ptr) - 1900;
	  *(--ptr) = 0;

	  ptr -= 3;
	  file_date->tm_mon = FTP_what_month (ptr) - 1;
	  *(--ptr) = 0;

	  ptr -= 2;
	  file_date->tm_mday = atoi (ptr);
	  *(--ptr) = 0;

	  while (isdigit (*(--ptr)));
	  sprintf (this_file.size, "%ld", atol (ptr) * 512);

	  strftime (this_file.date, sizeof (this_file.date), FTP_REMOTE_DATE_FORMAT, file_date);
	  this_file.date[0] = toupper (this_file.date[0]);

	  if (*(ptr1 = ptr2 + 1) == '[')
	    ptr1++;

	  *(ptr2 = strchr (ptr1, '(')) = 0;

	  if ((ptr = strchr (ptr1, ',')) == NULL)
	    if ((ptr = strchr (ptr1, ']')) == NULL)
	      ptr = strchr (ptr1, 32);

	  strncpy (this_file.uid, ptr1, ptr - ptr1);

	  if (*ptr == ',')
	    {
	      if ((ptr1 = strchr (ptr, ']')) == NULL)
		ptr1 = strchr (ptr, 32);
	      *ptr1 = 0;
	      strcpy (this_file.gid, ptr + 1);
	    }

	  /*ptr2 == attrib */

	  FTP_MISC_DEBUG_LOG_THIS_LINE ();

	  fwrite (&this_file, sizeof (this_file), 1, out);
	}
      break;


    }

  fclose (in);
  fclose (out);
#ifdef LIST_DEBUG
  DEBUG ("FTPmisc : FTP_format_dir_list END");
#endif
  return TRUE;
}


/* EOF */
