home *** CD-ROM | disk | FTP | other *** search
/ Mods Anthology 4 / Music-AmigaModsAnthology-4of4-Psychodk.mcsteam.iso / Tools / BeBox / Ralf_Tracker_0.3_Src / open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-16  |  5.0 KB  |  248 lines

  1. /* open.c */
  2.  
  3. /* Magic open file: path lookup and transparent decompression */
  4.  
  5. /* $Id: open.c,v 3.9 1993/11/17 15:31:16 espie Exp espie $ 
  6.  * $Log: open.c,v $
  7.  * Revision 3.9  1993/11/17  15:31:16  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 3.8  1993/11/11  20:00:03  espie
  11.  * Amiga support.
  12.  *
  13.  * Revision 3.7  1993/08/17  16:53:09  espie
  14.  * New gzip suffix.
  15.  *
  16.  * Revision 3.3  1993/07/14  16:33:41  espie
  17.  * Added gzip/shorten.
  18.  *
  19.  * Revision 3.2  1992/12/03  15:00:50  espie
  20.  * restore stty.
  21.  *
  22.  * Revision 3.1  1992/11/19  20:44:47  espie
  23.  * Protracker commands.
  24.  *
  25.  * Revision 3.0  1992/11/18  16:08:05  espie
  26.  * New release.
  27.  *
  28.  * Revision 1.5  1992/11/01  13:10:06  espie
  29.  * Cleaned up path handler, and some more bugs.
  30.  * Check for size now.
  31.  * Added path support. Transparent interface. We look up through the file
  32.  * list, which is small anyway.
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38. #ifdef AMIGA
  39. #include <stdlib.h>
  40. #else
  41. //#include <malloc.h>
  42. #endif
  43.  
  44. #include "defs.h"
  45. #include "extern.h"
  46.  
  47. LOCAL char *id = "$Id: open.c,v 3.9 1993/11/17 15:31:16 espie Exp espie $";
  48.  
  49. #define MAX_DESC 50 /* Maximum number of opened files */
  50.  
  51. LOCAL struct exfile 
  52.     {
  53.     FILE *handle;
  54.     int type;
  55.     } desc[MAX_DESC];
  56.  
  57. LOCAL int ixfile = 0;
  58.  
  59. #define REALFILE 1
  60. #define PIPEFILE 2
  61.  
  62. /* compression methods we do know about.
  63.  * Important restriction: for the time being, the output
  64.  * must be a single module.
  65.  */
  66.  
  67. LOCAL struct compression_method
  68.     {
  69.     char *extension;
  70.     char *command;
  71.     } comp_table[] =
  72.     {
  73.     ".gz",    "gzip -dc %s",
  74. #ifdef GZIP
  75.     ".z",    "gzip -dc %s",
  76. #else
  77.     ".Z",   "zcat %s",
  78. #endif
  79.     ".s",    "shorten -x %s -",
  80.     ".shn",    "shorten -x %s -",
  81.     ".zoo", "zoo xpq %s",
  82. #ifdef AMIGA
  83.     ".lzh", "lha -q p %s",
  84.     ".lha", "lha -q p %s",
  85. #else
  86.     ".lzh", "lha pq %s",
  87.     ".lha", "lha pq %s",
  88. #endif
  89.     ".zip", "unzip -pqq %s",
  90.     ".arc", "arc pn %s",
  91.     NULL,   NULL
  92.     };
  93.  
  94. /***
  95.  *
  96.  *  Handling extensions.
  97.  *
  98.  ***/
  99.  
  100. LOCAL BOOL check_ext(s, ext)
  101. char *s, *ext;
  102.     {
  103.     int ext_len, s_len;
  104.     char *c;
  105.  
  106.     ext_len = strlen(ext);
  107.     s_len = strlen(s);
  108.     if (s_len < ext_len)
  109.         return FALSE;
  110.     for (c = s + s_len - ext_len; *c; c++, ext++)
  111.         if (tolower(*c) != tolower(*ext))
  112.             return FALSE;
  113.     return TRUE;
  114.     }
  115.  
  116. LOCAL BOOL exist_file(fname)
  117. char *fname;
  118.     {
  119.     FILE *temp;
  120.  
  121.     temp = fopen(fname, "r");
  122.     if (temp)
  123.         {
  124.         fclose(temp);
  125.         return TRUE;
  126.         }
  127.     else
  128.         return FALSE;
  129.     }
  130.  
  131. #ifndef MAXPATHLEN
  132. #define MAXPATHLEN 350
  133. #endif
  134.  
  135. LOCAL char *find_file(fname, path)
  136. char *fname;
  137. char *path;
  138.     {
  139.     char *sep;
  140.     static char buffer[MAXPATHLEN];
  141.     int len;
  142.  
  143.         /* first, check the current directory */
  144.     if (exist_file(fname))
  145.         return fname;
  146.     while(path)
  147.         {
  148.         sep = strchr(path, ':');
  149.         if (sep)
  150.             len = sep - path;
  151.         else
  152.             len = strlen(path);
  153.         if (len < MAXPATHLEN)
  154.             {
  155.             strncpy(buffer, path, len);
  156.             buffer[len] = '/';
  157.             if (len + strlen(fname) < MAXPATHLEN - 5)
  158.                 {
  159.                 strcpy(buffer + len + 1, fname);
  160.                 puts(buffer);
  161.                 if (exist_file(buffer))
  162.                     return buffer;
  163.                 }
  164.             }
  165.         if (sep)
  166.             path = sep + 1;
  167.         else
  168.             return NULL;
  169.         }
  170.     return NULL;
  171.     }
  172.  
  173. FILE *open_file(fname, mode, path)
  174. char *fname;
  175. char *mode; /* right now, only mode "r" is supported */
  176. char *path; 
  177.     {
  178.     struct exfile *new;
  179.     struct compression_method *comp;
  180.  
  181.     if (mode[0] != 'r' || mode[1] != 0)
  182.         return NULL;
  183.     
  184.     if (ixfile == MAX_DESC)
  185.         return NULL;
  186.  
  187.     new = desc + ixfile++;
  188.  
  189.     fname = find_file(fname, path);
  190.     if (!fname)
  191.         return NULL;
  192. #ifdef __SUPPORT_PIPE__
  193.     for (comp = comp_table; comp->extension; comp++)
  194.         if (check_ext(fname, comp->extension))
  195.             {
  196.             char pipe[MAXPATHLEN + 25];
  197.  
  198.             sprintf(pipe, comp->command, fname);
  199.             new->type = PIPEFILE;
  200.             if (new->handle = popen(pipe, "r"))
  201.                 return new->handle;
  202.             else
  203.                 {
  204.                 ixfile--;
  205.                 return NULL;
  206.                 }
  207.             }
  208. #endif // of __SUPPORT_PIPE__
  209.     new->type = REALFILE;
  210.     if ((new->handle = fopen(fname, "r")))
  211.         return new->handle;
  212.     else
  213.         {
  214.         ixfile--;
  215.         return NULL;
  216.         }
  217.     }
  218.  
  219.  
  220. void close_file(file)
  221. FILE *file;
  222.     {
  223.     if (file)
  224.         {
  225.         int i;
  226.  
  227.         for (i = 0; i < ixfile; i++)
  228.             if (desc[i].handle == file)
  229.                 {
  230.                 switch(desc[i].type)
  231.                     {
  232.                 case REALFILE:
  233.                     fclose(file);
  234.                     break;
  235. #ifdef __SUPPORT_PIPE__
  236.                 case PIPEFILE:
  237.                     pclose(file);
  238.                     break;
  239. #endif // of __SUPPORT_PIPE__
  240.                     }
  241.                 ixfile--;
  242.                 desc[i].handle = desc[ixfile].handle;
  243.                 desc[i].type = desc[ixfile].type;
  244.                 }
  245.             }
  246.     }
  247.  
  248.