/*
   <p>Open a file in the search path.</p>

   <kbd>
   <b>environ - C programming support functions</b><br>
   Copyright (C) 2005  Martin C Gregorie
   
   This program is free software; you can redistribute it and/or
   modify it under the terms of the Lesser GNU General Public License.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the Lesser GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   </kbd>
  
   <p>Contact Martin Gregorie at <i>martin@gregorie.org</i></p>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "environ.h"

/*
   Open <u>file</u> in <u>mode</u> and trace the action if <u>debug</u>
   is non-zero. Return the result of the internal <i>fopen()</i> call.
*/
FILE* checkopen(char *name, char *mode, int debug)
{
   if (debug)
   {
      printf("trying to open %s as '%s'\n",name,mode);
   }
   
   return fopen(name,mode);
}

/*
   Try to open <u>name</u> using <u>mode1</u>. If this doesn't work
   try <u>mode2</u>. Trace the operations if <u>debug</u> is non-zero.
   Return the result of the last <i>fopen()</i> tried.
*/
FILE* opentwice(char *name, char *mode1, char *mode2, int debug)
{
   FILE  *f;
   
   f = checkopen(name,mode1,debug);
   if (!f)
   {
      f = checkopen(name,mode2,debug);
   }
   
   return f;
}

/*
   Search for and open a file within a predefined search path.

   An attempt to open a file whose local name is <u>name</u>, trying
   <u>mode1</u> then <u>mode2</u>. The modes are the normal ones used
   with the <i>FILE*</i> buffered i/o system.

   This is tried first in the current directory and then
   in each directory in turn in the list specified
   by the <u>list</u> environment variable.
   The list must the normal searchpath ($PATH) format using the system
   default directory separators.

*/
FILE* searchpath(char *list, char *name, char *mode1, char *mode2, int debug)
{
   FILE  *f;
   char  *lstring;
   char  *end;
   char  *temp;
   int   len;

   f = opentwice(name,mode1,mode2,debug);
   if (f)
   {
      return f;         /* found file in current or execution dir */
   }

   lstring = getenv(list);   /* pick up search path */
   if (!lstring)
   {
      return (FILE*)lstring;   /* failed to get environment string */
   } 

   len = strlen(lstring);
   while (lstring && f == NULL)
   {
      end = index(lstring, SEARCHSEP);
      if (end)
      {
         *end++ = 0;
      }
      
      len = strlen(name) + strlen(lstring) + 2;
      if ((temp = (char*)malloc(len)) == NULL)
      {
         error(progname(),"can't get memory allocation for",
               "searchpath()");
      }
      strcpy(temp,lstring);
      strcat(temp,"/");
      strcat(temp,name);
      f = opentwice(temp,mode1,mode2,debug);
      free(temp);
      lstring = end;
   }
   return f;
}


