 /*
  * Khoros: $Id: listfile.c,v 1.2 1991/12/18 09:54:42 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: listfile.c,v 1.2 1991/12/18 09:54:42 dkhoros Exp $";
#endif

 /*
  * $Log: listfile.c,v $
 * Revision 1.2  1991/12/18  09:54:42  dkhoros
 * HellPatch3
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"        /* Copyright 1990 by UNM */
#include "vgparm.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>     file name: listfile.c                             <<<<
   >>>>                                                       <<<<
   >>>>   description: File Utility                           <<<<
   >>>>                                                       <<<<
   >>>>      routines: vlistfile()                            <<<<
   >>>>                                                       <<<<
   >>>> modifications:                                        <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


#define MaxEntries 25

/********************************************************
*
*  MODULE NAME: vlistfile
*
*     PURPOSE: This module is used to create a list from the
*	       supplied file.  It reads the arguments out of the
*	       specified file and returns them in an array of
*	       strings.  The programmer also has the option of
*	       specifying if they want the resulting string sorted
*	       or not.
*
*       INPUT:  filename    - base name of the files to be listed.
*		global_dir  - the global directory is used as a prefix
*			      to the filename
*		sort_list   - a flag indicating whether we are to sort
*			      the list before returning
*		num_entries - the number of entries in the list that
*			      are returned.
*
*      OUTPUT:  returns a list of strings to the names in the file upon
*		successful completion of this routine, otherwise NULL is
*		returned.
*
* CALLED FROM:
*
* WRITTEN BY:  Mark Young
*
********************************************************/


char **vlistfile(filename, global_dir, sort_list, num_entries)

char *filename, *global_dir;
int  sort_list, *num_entries;
{
	FILE    *file;
	int	c, num, size;
	char    character, *fullpath, entry[LENGTH], **list;


	*num_entries = 0;
	if (global_dir == NULL && filename == NULL)
	{
	   (void) fprintf(stderr,"\nvlistfile:\n");
	   (void) fprintf(stderr,"   Error!  NULL input filename and directory \
 encountered.\n");
	   return(NULL);
	}

	/*
	 *  Expand the path to get the full path to the directory.
	 */
	if (VStrlen(filename) == 0)
	   fullpath = vfullpath(global_dir, NULL, NULL);
	else
	   fullpath = vfullpath(filename, global_dir, NULL);

	/*
	 *  Open the file
	 */
	if ((file = fopen(fullpath, "r")) == NULL)
	{
	   fprintf(stderr, "Error!  Unable to open file '%s'.\n", fullpath);
	   free(fullpath); return(NULL);
	}

	/*
	 *  Malloc the array of filenames.
	 */
	num  = 0;
	size = MaxEntries;
	if ((list = (char **) malloc(size * sizeof(char *))) == NULL)
	{
	   (void) fprintf(stderr,"\nvlistfile:\n");
	   (void) fprintf(stderr,"   Error!  Unable to allocate enough memory \
for directory list.\n");
	   free(fullpath); return(NULL);
	}

	while (!feof(file))
	{
	   if (fscanf(file, " %[#]", &character) == 1)
	   {
	      /*
	       *  Read to the rest of the comment which should be until
	       *  the end of the line.
	       */
	      do
	      {
		 if (fgets(entry, LENGTH, file) == NULL)
		    break;
	      } while (VStrlen(entry) >= LENGTH);

	   }
	   else if (fscanf(file, "%[/]%[*]", &character, &character) == 2)
	   {
	      for (;;)
	      {
		  while ((c = fgetc(file)) != '*' && c != EOF && c != '\0')
				;

		  if (c == '*')
		  {
		     if ((c = fgetc(file)) == '/')
			break;
		  }
		  else
		     break;
	      }
	   }
	   else if (fscanf(file,"%s", entry) == 1)
	   {
	      /*
	       *  Make sure that we have enough room to add the filename to
	       *  the directory listing array.
	       */
	      if (num == size)
	      {
	         size += MaxEntries;
	         list = (char **) realloc(list, size * sizeof(char *));
	         if (list == NULL)
	         {
	            (void) fprintf(stderr,"\nvlistfile:\n");
	            (void) fprintf(stderr,"  Error!  Unable to allocate enough \
memory for file listing.\n");
	            return(NULL);
	          }
	      }
	      list[num++] = VStrcpy(entry);
	   }
	}

	/*
	 *  Cleanup time.  Free the fullpath.  We need to make sure that the
	 *  list of names is greater than 0.  If not then free the list and
	 *  set it to *  NULL, otherwise we need to see if the user wants to
	 *  sort the entries into descending order.
	 */
	free(fullpath);
	if (num == 0)
	{
	   free(list);
	   list = NULL;
	} 
	else if (sort_list)
	{
	   list = vsortlist(list, num, TRUE);
	}
	*num_entries = num;
	return(list);
}
