/****************************************************************
 * This software is Copyright (C) 1986-1998 by                  *
 *                                                              *
 * F6FBB - Jean-Paul ROUBELAT,  jpr@f6fbb.org                   *
 * 6, rue George Sand                                           *
 * 31120 - Roquettes - France                                   *
 *                                                              *
 * License to copy and use this software is granted for         *
 * non-commercial use provided that it is identified as         *
 *                                                              *
 * "FBB packet-radio BBS software by Jean-Paul ROUBELAT, F6FBB" *
 *                                                              *
 * in all material mentioning or referencing this software      *
 * or this function.                                            *
 *                                                              *
 * These notices must be retained in any copies of any part of  *
 * this documentation and/or software.                          *
 *                                                              *
 * Parts of code have been taken from many other softwares.     *
 * Thanks for the help.                                         *
 ****************************************************************/

#include <serv.h>
#ifdef __LINUX__
#include <utime.h>
#endif

static int dir_time (char *);

static long parcours (char, char *);

int is_dir (char *chaine)
{
#ifdef __LINUX__
	struct stat st;
	int ret;

	if ((strlen (chaine) > 2) && (chaine[1] == ':'))
		chaine += 2;
	ret = stat (back2slash (chaine), &st);
	if (ret == -1)
		return (0);

	return (S_ISDIR (st.st_mode));
#endif
#if defined(__FBBDOS__) || defined (__WINDOWS__)
	int hand;
	struct dfree dtable;


/* Teste la racine car NOVELL ne reconnait pas C:\ comme repertoire !!! */

	if ((isalpha (chaine[0])) && (chaine[1] == ':') && (chaine[2] == '\\') && (!chaine[3]))
	{
		getdfree (toupper (chaine[0]) - '@', &dtable);
		if (dtable.df_sclus == 0xffff)
		{
			/* Disque non valide ? */
			return (0);
		}
		else
			return (1);
	}

/* Fin du rajout NOVELL */

	if (access (chaine, 0) == 0)
	{
		hand = open (chaine, O_RDONLY);		/* Repertoire ou fichier ? */
		if (hand == -1)
		{
			return (1);
		}
		else
		{
			close (hand);
			return (0);
		}
	}
	return (0);
#endif
}


void prompt_dos (void)
{
	char *scan;
	char *ptr = local_path (pvoie->dos_path);

	if ((scan = strchr (ptr, ':')) != NULL)
		ptr = scan + 1;
	var_cpy (0, ptr);
	texte (T_DOS + 0);
	maj_niv (9, 0, 0);
}


static int dir_time (char *indic)
{
	int lg = strlen (indic);
	int pos;
	int c[3];

	for (pos = 0; pos < 3; c[pos++] = '\0')
		;

	pos = 0;

	while (lg--)
	{
		if (isalpha (indic[lg]))
			c[pos++] = (int) (indic[lg] - 'A');
		if (pos == 3)
			break;
	}

	return (c[0] | (c[1] << 5) | (c[2] << 10));
}


void wr_dir (char *fichier, char *indic)
{
#if defined(__FBBDOS__) || defined(__WINDOWS__)
	int fd;
	int dt = dir_time (indic);
	long temps = time (NULL);
	struct tm *sdate;
	struct ftime dirtime;

	sdate = localtime (&temps);

	dirtime.ft_year = sdate->tm_year - 80;
	dirtime.ft_day = sdate->tm_mday;
	dirtime.ft_month = sdate->tm_mon + 1;
	dirtime.ft_hour = dt >> 11;
	dirtime.ft_min = (dt >> 5) & 0x3f;
	dirtime.ft_tsec = dt & 0x1f;

	if ((fd = open (fichier, O_RDONLY)) != -1)
	{
		setftime (fd, &dirtime);
		close (fd);
	}
#endif
#ifdef __LINUX__
	struct utimbuf buf;
	long temps = time (NULL);
	struct tm *sdate;
	int dt = dir_time (indic);

	int heure = dt >> 11;
	int minute = (dt >> 5) & 0x3f;
	int seconde = (dt & 0x1f) << 1;

	sdate = localtime (&temps);

	sdate->tm_hour = heure;
	sdate->tm_min = minute;
	sdate->tm_sec = seconde;

	/*
	   printf("Ecrit : heure=%d min=%d sec=%d\n", sdate->tm_hour, sdate->tm_min, sdate->tm_sec);
	 */
	buf.actime = buf.modtime = mktime (sdate);
	if (utime (back2slash (fichier), &buf) != 0)
		perror ("utime");
#endif
}


int aut_dir (char *fichier, char *indic)
{
#if defined(__FBBDOS__) || defined(__WINDOWS__)
	union
	{
		struct ftime dirtime;
		struct
		{
			int time;
			int date;
		}
		dtime;
	}
	utime;
	int fd;

	if (droits (SUPFIC))
		return (1);

	if ((fd = open (fichier, O_RDONLY)) == -1)
		return (1);
	getftime (fd, &(utime.dirtime));
	close (fd);
	return (utime.dtime.time == dir_time (indic));
#endif
#ifdef __LINUX__
	int fd;
	struct stat buf;
	time_t temps;
	struct tm *sdate;
	int dt;

	if ((fd = open (fichier, O_RDONLY)) == -1)
		return (1);
	fstat (fd, &buf);
	temps = buf.st_mtime;
	close (fd);
	sdate = localtime (&temps);
	printf ("Lit : heure=%d min=%d sec=%d\n", sdate->tm_hour, sdate->tm_min, sdate->tm_sec);
	dt = (sdate->tm_hour << 11) + (sdate->tm_min << 5) + (sdate->tm_sec >> 1);
	return (dt == dir_time (indic));
#endif
}


int aut_ecr (char *fichier)
{
	FILE *fptr;
	int supp = TRUE;
	char *ptr, *scan;
	char ligne[81];
	char nomfich[256];

	if (droits (ACCESDOS) && droits (SUPFIC) && (*fichier == '+'))
	{
		ptr = scan = fichier;
		if (*scan == '+')
			++scan;
		while ((*ptr++ = *scan++) != '\0')
			;
	}
	else
	{
#ifdef __FBBDOS__
		if ((fptr = fopen (d_disque ("prot_d.sys"), "r")) == NULL)
#endif
#ifdef __WINDOWS__
			if ((fptr = fopen (d_disque ("prot_w.sys"), "r")) == NULL)
#endif
#ifdef __LINUX__
				if ((fptr = fopen (d_disque ("prot_l.sys"), "r")) == NULL)
#endif
				{
					if ((fptr = fopen (d_disque ("protect.sys"), "r")) == NULL)
					{
						supp = FALSE;
					}

				}

		if (fptr)
		{
			while (fgets (ligne, 80, fptr))
			{
				if (*ligne == '#')
					continue;
				ptr = scan = ligne;
				while ((*scan) && (!ISGRAPH (*scan)))
					++scan;
				while (ISGRAPH (*scan))
					*ptr++ = *scan++;
				*ptr = '\0';
				strcpy (nomfich, tot_path (fichier, pvoie->dos_path));
				ptr = strrchr (nomfich, '\\');
				if (ptr == nomfich)
					strcpy (nomfich, "\\");
				else
					*ptr = '\0';
				if (strcmp (ligne, nomfich) == 0)
				{
					supp = FALSE;
					break;
				}
			}
			ferme (fptr, 77);
			if ((supp) && (!droits (ACCESDOS)))
			{
				strcpy (nomfich, tot_path (fichier, pvoie->dos_path));
				supp = aut_dir (nomfich, pvoie->sta.indicatif.call);
			}
		}
	}

	if (!supp)
	{
		strcpy (pvoie->appendf, fichier);
		texte (T_ERR + 23);
	}
	return (supp);
}


/*
   static int   exist(char*file)
   {
   return (access(local_path(tot_path(file, pvoie->dos_path)), 0) == 0) ;
   }
 */

void remove_dir (void)
{
	char *ptr;

	strtok (indd, " \r");
	if ((ptr = strtok (NULL, " \r")) == NULL)
	{
		texte (T_ERR + 25);
	}
	else
	{
		if (tst_point (ptr))
		{
			if (aut_ecr (ch_slash (ptr)))
			{
				var_cpy (0, ptr);
#ifdef __LINUX__
				if (fbb_rmdir (tot_path (ptr, pvoie->dos_path)) == 0)
#else
				if (rmdir (tot_path (ptr, pvoie->dos_path)) == 0)
#endif
					texte (T_DOS + 1);
				else
					texte (T_ERR + 24);
			}
		}
	}
	prompt_dos ();
}


void make_dir (void)
{
	char *ptr;

	strtok (indd, " \r");
	if ((ptr = strtok (NULL, " \r")) == NULL)
	{
		texte (T_ERR + 25);
	}
	else
	{
		ch_slash (ptr);
#ifdef __LINUX__
		if (fbb_mkdir (tot_path (ptr, pvoie->dos_path), 0777) != 0)
		{
			var_cpy (0, ptr);
			texte (T_ERR + 26);
		}
#endif
#if defined(__FBBDOS__) || defined(__WINDOWS__)
		if (mkdir (tot_path (ptr, pvoie->dos_path)) != 0)
		{
			var_cpy (0, ptr);
			texte (T_ERR + 26);
		}
#endif
	}
	prompt_dos ();
}


static void teste_file_name (char *ptr)
{
	int ok;
	int lg = 0;
	int max = 8;
	char *ptro = ptr;

	while (*ptr)
	{

		ok = 1;
		if (*ptr == '.')
		{
			lg = 0;
			max = 3;
		}
		else if (*ptr == '\\')
		{
			lg = 0;
			max = 8;
		}
		else if (++lg > max)
		{
			ok = 0;
		}

		if (ok)
			*ptro++ = *ptr;
		++ptr;
	}
	*ptro = '\0';
}

void change_dir (void)
{
	int nb;
	char local_dir[256], *ptr, *scan, *cur_dir;

	strcpy (local_dir, pvoie->dos_path);
	strtok (indd, " \r");
	if ((ptr = strtok (NULL, " \r")) == NULL)
	{
		nb = strlen (local_dir);
		if (nb > 1)
		{
			--nb;
			local_dir[nb] = '\0';
		}
		outln (local_dir, nb);
	}
	else
	{
		ch_slash (ptr);
		teste_file_name (ptr);
		if (*ptr == '\\')
		{
			if (tst_point (ptr))
			{
				strcpy (local_dir, ptr);
				if (strlen (local_dir) > 1)
					strcat (local_dir, "\\");
			}
		}
		else
		{
			if ((scan = strtok (ptr, "\\\r")) != NULL)
			{
				do
				{
					if (strcmp (scan, ".") == 0)
						continue;
					if (strncmp (scan, "..", 2) == 0)
					{
						cur_dir = strrchr (local_dir, '\\');
						if (cur_dir != local_dir)
						{
							do
							{
								*cur_dir-- = '\0';
							}
							while (*cur_dir != '\\');
						}
					}
					else
					{
						strcat (local_dir, scan);
						strcat (local_dir, "\\");
					}
				}
				while ((scan = strtok (NULL, "\\\r")) != NULL);
			}
		}
		if (strlen (local_dir) > 40)
			texte (T_ERR + 28);
		else
		{
			if (is_dir (local_path (tot_path ("\0", local_dir))) > 0)
				strcpy (pvoie->dos_path, local_dir);
			else
				texte (T_ERR + 29);
		}
	}
	prompt_dos ();
}


char *dir_date (int date)
{
	int jour, mois, annee;
	static char ch_date[11];

	jour = date & 0x1f;
	mois = (date >> 5) & 0x0f;
	annee = 80 + ((date >> 9) & 0x3f);
	sprintf (ch_date, "%02d-%02d-%02d", jour, mois, annee % 100);
	return (ch_date);
}

int dir_suite (char *masque)
{
	int n;
	char chaine[257];
	char temp[257];

	if (masque)
	{

		strcpy (temp, tot_path (ch_slash (masque), pvoie->dos_path));

		n = strlen (temp);
		if ((n > 3) && (temp[n - 1] == '\\'))
			temp[n - 1] = '\0';
		if (is_dir (temp))
		{
			if ((strlen (masque) == 3) && (masque[2] == '\\'))
				masque[2] = '\0';
#ifdef __LINUX__
			sprintf (chaine, "%s/*", masque);
#else
			sprintf (chaine, "%s/*.*", masque);
#endif
			masque = chaine;
		}

		if (findfirst (tot_path (ch_slash (masque), pvoie->dos_path), &(pvoie->dirblk), FA_DIREC))
		{
			texte (T_DOS + 2);
			return (FALSE);
		}
		if (*pvoie->dirblk.ff_name == '.')
		{
			findnext (&(pvoie->dirblk));
			if (findnext (&(pvoie->dirblk)))
			{
				texte (T_DOS + 2);
				return (FALSE);
			}
		}
		sprintf (varx[0], "%-13s", pvoie->dirblk.ff_name);
		var_cpy (2, dir_date (pvoie->dirblk.ff_fdate));
		*varx[3] = '\0';
		if ((pvoie->dirblk.ff_attrib & FA_DIREC) != 0)
		{
			var_cpy (1, "<DIR>  ");
		}
		else
		{
			sprintf (varx[1], "%7ld", pvoie->dirblk.ff_fsize);
		}

		if (findnext (&(pvoie->dirblk)))
		{
			*varx[4] = *varx[5] = *varx[6] = *varx[7] = '\0';
			texte (T_DOS + 3);
			return (FALSE);
		}

		sprintf (varx[4], "%-13s", pvoie->dirblk.ff_name);
		var_cpy (6, dir_date (pvoie->dirblk.ff_fdate));
		*varx[7] = '\0';
		if ((pvoie->dirblk.ff_attrib & FA_DIREC) != 0)
		{
			var_cpy (5, "<DIR>  ");
		}
		else
		{
			sprintf (varx[5], "%7ld", pvoie->dirblk.ff_fsize);
		}
		texte (T_DOS + 3);
	}

	while (1)
	{
		if (findnext (&(pvoie->dirblk)))
			return (FALSE);
		sprintf (varx[0], "%-13s", pvoie->dirblk.ff_name);
		var_cpy (2, dir_date (pvoie->dirblk.ff_fdate));
		*varx[3] = '\0';
		if ((pvoie->dirblk.ff_attrib & FA_DIREC) != 0)
		{
			var_cpy (1, "<DIR>  ");
		}
		else
		{
			sprintf (varx[1], "%7ld", pvoie->dirblk.ff_fsize);
		}

		if (findnext (&(pvoie->dirblk)))
		{
			*varx[4] = *varx[5] = *varx[6] = *varx[7] = '\0';
			texte (T_DOS + 3);
			return (FALSE);
		}

		sprintf (varx[4], "%-13s", pvoie->dirblk.ff_name);
		var_cpy (6, dir_date (pvoie->dirblk.ff_fdate));
		*varx[7] = '\0';
		if ((pvoie->dirblk.ff_attrib & FA_DIREC) != 0)
		{
			var_cpy (5, "<DIR>  ");
		}
		else
		{
			sprintf (varx[5], "%7ld", pvoie->dirblk.ff_fsize);
		}
		texte (T_DOS + 3);
	}
	/*   return(TRUE) ; */
}


void retour_dir (char vdisk)
{
	int disk;

	if (vdisk == 8)
		disk = (pvoie->finf.priv[1] == ':') ? pvoie->finf.priv[0] - '@' : getdisk () + 1;
	else if ((voiecur == CONSOLE) || (pvoie->niv1 == N_YAPP))
		disk = vdisk + 1;
	else
#ifdef __LINUX__
		disk = vdisk + 1;
#else
		disk = PATH[vdisk][0] - '@';
#endif
	ultoa (free_disk (disk) * 1024UL, varx[0], 10);
	texte (T_DOS + 11);
	retour_dos ();
}

void dir (void)
{
	char vdisk;
	char *ptr;

#ifdef __LINUX__
	char temp[] = "X:*";

#else
	char temp[] = "X:*.*";

#endif

	strtok (indd, " \r");
	pvoie->noenr_menu = 0L;
	ptr = strtok (NULL, " \r");

	if (ptr == NULL)
	{
		temp[0] = (pvoie->vdisk == 8) ? 'P' : pvoie->vdisk + 'A';
		ptr = temp;
	}

	vdisk = pvoie->vdisk;

	if ((*(ptr + 1) == ':') && (*(ptr + 2) == '\0'))
	{
		temp[0] = *ptr;
		vdisk = *ptr - 'A';
		if (vdisk == 15)
			vdisk = 8;
		ptr = temp;
	}

	if (!tst_point (ptr))
		retour_dos ();

	else if (dir_suite (ptr))
	{
		texte (T_TRT + 11);
		maj_niv (9, 1, 1);
	}
	else
		retour_dir (vdisk);
}


void list (void)
{
	char vdisk;
	char *ptr;

#ifdef __LINUX__
	char temp[] = "X:*";

#else
	char temp[] = "X:*.*";

#endif

	strtok (indd, " \r");
	ptr = strtok (NULL, " \r");
	if (ptr == NULL)
	{
		temp[0] = (pvoie->vdisk == 8) ? 'P' : pvoie->vdisk + 'A';
		ptr = temp;
	}

	vdisk = pvoie->vdisk;

	if ((*(ptr + 1) == ':') && (*(ptr + 2) == '\0'))
	{
		temp[0] = *ptr;
		vdisk = *ptr - 'A';
		if (vdisk == 13)
			vdisk = 8;
		ptr = temp;
	}

#if 0
	if ((ptr = strtok (NULL, " \r")) == NULL)
	{
		ptr = temp;
	}
	liste_label ();
	if (!tst_point (ptr))
		retour_dos ();

	if (dir_yapp (ptr))
	{
		texte (T_TRT + 11);
		ch_niv3 (1);
	}
	else
	{
		pvoie->noenr_menu = 0L;
		libere_label (voiecur);
		retour_dir ();
	}
#endif
	if (tst_point (ptr))
	{
		dir_yapp (ptr);
		retour_dir (vdisk);
	}
	else
		retour_dos ();
}

static long parcours (char vdisk, char *path)
{
	struct ffblk ffblk;
	long total = 0L;
	long local = 0L;
	char rech[80];
	char temp[128];
	int done = 1;
	int pos;

	strcpy (rech, path);
#ifdef __LINUX__
	strcat (rech, "*");
#else
	strcat (rech, "*.*");
#endif

	if (voiecur == CONSOLE)
		pos = 0;
	else
		pos = strlen (PATH[(int)vdisk]) - 1;

	done = findfirst (rech, &ffblk, FA_DIREC);
	while (!done)
	{
		if (*ffblk.ff_name != '.')
		{
#ifdef __LINUX__
			if ((ffblk.ff_attrib & FA_DIREC) && ((ffblk.ff_attrib & FA_LINK) == 0))
#else
			if (ffblk.ff_attrib & FA_DIREC)
#endif
			{
				strcpy (temp, path);
				strcat (temp, ffblk.ff_name);
				strcat (temp, "\\");
				if (strncmp (temp + 1, ":\\PROC\\", 7) != 0)
				{
					total += parcours (vdisk, temp);
				}
			}
			else
			{
				local += ffblk.ff_fsize;
			}
		}
		done = findnext (&ffblk);
	}
	total += local;
	sprintf (temp, "%-10ld %-10ld %s", total, local, path + pos);
	outln (temp, strlen (temp));

	return (total);
}

void du (void)
{
	char vdisk;
	char *ptr;
	char temp[] = "X:";
	char path[256];

	strtok (indd, " \r");
	ptr = strtok (NULL, " \r");
	if (ptr == NULL)
	{
		temp[0] = (pvoie->vdisk == 8) ? 'P' : pvoie->vdisk + 'A';
		ptr = temp;
	}

	vdisk = pvoie->vdisk;

	if ((*(ptr + 1) == ':') && (*(ptr + 2) == '\0'))
	{
		temp[0] = *ptr;
		vdisk = *ptr - 'A';
		if (vdisk == 13)
			vdisk = 8;
		ptr = temp;
	}

	if (tst_point (ptr))
	{
		strcpy (path, tot_path (ch_slash (ptr), pvoie->dos_path));
		parcours (vdisk, path);
		retour_dir (vdisk);
	}
	else
		retour_dos ();
}
