char *ckdirv = "CTOS directory function-1.01, Summer 1987";

/* C K C T O S D I R . C -- Directory function for CTOS C-Kermit */

/* Joel Dunn, UNC-CH, February 1987 */

/* Includes */

#include "ctermi.h"
#include "ctcmd.h"
#include "ctuser.h"
#include <ctype.h>

/* P R I N T D I R - Print sorted directory */

printdir()
{

	struct direntry
		{
		char fname[51];	    /* 50 bytes for name, null terminator */
		long int fsize;
		} *pcurdirel;		/* pointer to a file name/size */
	struct ucbtype			/* CTOS user control block */
		{
		int reserved;
		char sizevol;
		char volname[12];
		char sizedir;
		char dirname[12];
		char sizepw;
		char password[12];
		} ucb;
	int x, y, z;			/* general purpose integers */
	int isector;			/* count of sector processed */
	int numdirentry;		/* number of directory entries found */
	int maxnumdirentry;		/* max number of directory entries */
	int fhnumber;			/* file header for fileheaders.sys */
	int fhandle;			/* file handle for fileheaders.sys */
	int erc;			/* CTOS error number */
	int openerc;			/* CTOS error number for openfile*/
	int *pfhnumber;			/* pointer to file header */
	int strcmp();			/* string comparison function */
	unsigned int sizedirarray;	/* size of directory array in bytes */
	long int numdirsectors;		/* number of directory sectors */
	long int lfa;			/* logical file address */
	long int *pfsize;		/* pointer to file size */
	long int totalsize;		/* total of file sizes */
	long int tempdirsize;		/* temporary calculation field */
	char *pdirpage;			/* pointer to a directory page */
	char *psavedirpage;		/* save pointer to a directory page */
	char *pfileheader;		/* pointer to a file header */
	char *pdirarray;		/* pointer to file names/sizes */
	char *fileheadername = "<sys>fileheaders.sys";
					/* name of fileheader for volume */
	void qsort();			/* function returns a void type */

	/* get number of directory sectors */
	if (getucb(&ucb, sizeof(ucb))) return(0);
	if (getdirstatus(&ucb.dirname[0], ucb.sizedir, &ucb.password[0],
			 ucb.sizepw, 0, &numdirsectors, 4))
	  return(0);
	numdirsectors /= 512;

	/* allocate storage for filenames & sizes
	   size = 25 files/sector x numdirsectors x # of bytes in structure */
	maxnumdirentry = 25*numdirsectors;
	tempdirsize = 55l;
	tempdirsize *= maxnumdirentry;
	if (tempdirsize > 0xffffl) 
		{
		printf("\nDirectory too large\n");
		return(0);
		}
	else sizedirarray = tempdirsize;
	if (allocmemorysl(sizedirarray, &pdirarray)) return(0);

	/* allocate storage for a directory page */
	if (allocmemorysl(512, &psavedirpage)) return(0);

	/* allocate storage for a fileheader */
	if (allocmemorysl(512, &pfileheader)) return(0);

	/* load directory array with name and file size
	   ...format per page is: 1 null byte
                                  1 byte with length of name
                                  n bytes, file name
                                  2 bytes, file header number
*/
	pcurdirel = pdirarray;
	isector = 0;
	numdirentry = 0;
	openerc = openfile(&fhandle, fileheadername, strlen(fileheadername),
						fileheadername, 0, 0x6d72);
	while (isector < numdirsectors)
		{
		pdirpage = psavedirpage; /* set up working pointer */
		if (readdirsector(&ucb.dirname[0],
				  ucb.sizedir, &ucb.password[0],
				  ucb.sizepw, isector++, pdirpage))
		  return(0);
		pdirpage++; /* burn null byte */
		while (*pdirpage && *(pdirpage+1) && *(pdirpage+2))
			{
			x = *pdirpage++; /* get length of name */
			for (y = 0; y < 51; y++)
				if (y < x)
					{
					z = *pdirpage++;
					if (islower(z)) z = _toupper(z);
					pcurdirel->fname[y] = z;
					}
				else pcurdirel->fname[y] = 0x00;
			numdirentry++;

			/* get file size */
			pfhnumber = pdirpage;
			fhnumber = *pfhnumber;
			pcurdirel->fsize = 0l;
			if (!openerc)
				{
				lfa = fhnumber;
				lfa *= 512l;
				erc = read(fhandle, pfileheader, 512, lfa, &z);
				if (!erc)
					{
					pfsize = pfileheader+111;
					pcurdirel->fsize = *pfsize;
					}
				}
			pdirpage += 2;	/* burn bytes for fileheader */
			pcurdirel++;	/* forward by 1 structure-length */
			}
		}
	if (close(fhandle)) return(0);

	/* sort directory array */
	qsort(pdirarray, numdirentry, 55, strcmp);

	/* print out directory entries */
	printf("\377PN");		/* video pause on */
	totalsize = 0;
	pcurdirel = pdirarray;
	printf(
	"\nFilename                                          Length\n\n");
	for (x = 0; x < numdirentry; x++)
		{
		printf("%s", pcurdirel->fname);
		y = strlen(pcurdirel->fname);
		if (y > 50) y = 50;
		y = 51 - y;
		for (z = 0; z < y; z++) printf(" ");
		printf("%ld\n", pcurdirel->fsize);
		totalsize += pcurdirel->fsize;
		pcurdirel++;
		}
	printf("\n%d files, totalling %ld bytes\n",numdirentry,totalsize);
	printf("\377PF");		/* video pause off */

	/* deallocate storage used */
	if (deallocmemorysl(pfileheader, 512)) return(0);
	if (deallocmemorysl(psavedirpage, 512)) return(0);
	if (deallocmemorysl(pdirarray, sizedirarray)) return(0);
	return(0);
}
