common.c
上传用户:nini_0081
上传日期:2022-07-21
资源大小:2628k
文件大小:6k
源码类别:

多媒体编程

开发平台:

DOS

  1. /*
  2.     TiMidity -- Experimental MIDI to WAVE converter
  3.     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.    common.c
  16.    */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include "config.h"
  22. #include "common.h"
  23. #include "output.h"
  24. #include "ctrlmode.h"
  25. /* I guess "rb" should be right for any libc */
  26. #define OPEN_MODE "rb"
  27. char current_filename[PATH_MAX];
  28. static PathList *pathlist=NULL;
  29. /* Try to open a file for reading. If the filename ends in one of the 
  30.    defined compressor extensions, pipe the file through the decompressor */
  31. static FILE *try_to_open(const char *name, int decompress, int noise_mode)
  32. {
  33.   FILE *fp;
  34.   fp=fopen(name, OPEN_MODE); /* First just check that the file exists */
  35.   if (!fp)
  36.     return 0;
  37. #ifdef DECOMPRESSOR_LIST
  38.   if (decompress)
  39.     {
  40.       int l,el;
  41.       static char *decompressor_list[] = DECOMPRESSOR_LIST, **dec;
  42.       const char *cp;
  43.       char tmp[PATH_MAX], tmp2[PATH_MAX], *cp2;
  44.       /* Check if it's a compressed file */ 
  45.       l=strlen(name);
  46.       for (dec=decompressor_list; *dec; dec+=2)
  47. {
  48.   el=strlen(*dec);
  49.   if ((el>=l) || (strcmp(name+l-el, *dec)))
  50.     continue;
  51.   /* Yes. Close the file, open a pipe instead. */
  52.   fclose(fp);
  53.   /* Quote some special characters in the file name */
  54.   cp=name;
  55.   cp2=tmp2;
  56.   while (*cp)
  57.     {
  58.       switch(*cp)
  59. {
  60. case ''':
  61. case '\':
  62. case ' ':
  63. case '`':
  64. case '!':
  65. case '"':
  66. case '&':
  67. case ';':
  68.   *cp2++='\';
  69. }
  70.       *cp2++=*cp++;
  71.     }
  72.   *cp2=0;
  73.   sprintf(tmp, *(dec+1), tmp2);
  74.   fp=popen(tmp, "r");
  75.   break;
  76. }
  77.     }
  78. #endif
  79.   
  80.   return fp;
  81. }
  82. /* This is meant to find and open files for reading, possibly piping
  83.    them through a decompressor. */
  84. FILE *open_file(const char *name, int decompress, int noise_mode)
  85. {
  86.   FILE *fp;
  87.   PathList *plp;
  88.   int l;
  89.   if (!name || !(*name))
  90.     {
  91.       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Attempted to open nameless file.");
  92.       return 0;
  93.     }
  94.   if (pathlist==NULL) {
  95.     /* Generate path list */
  96. #ifdef DEFAULT_PATH
  97.     add_to_pathlist(DEFAULT_PATH);
  98. #endif
  99. #ifdef DEFAULT_PATH1
  100.     add_to_pathlist(DEFAULT_PATH1);
  101. #endif
  102. #ifdef DEFAULT_PATH2
  103.     add_to_pathlist(DEFAULT_PATH2);
  104. #endif
  105.   }
  106.   /* First try the given name */
  107.   strncpy(current_filename, name, PATH_MAX - 1);
  108.   current_filename[PATH_MAX - 1]='';
  109.   ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
  110.   if ((fp=try_to_open(current_filename, decompress, noise_mode)))
  111.     return fp;
  112. #ifdef ENOENT
  113.   if (noise_mode && (errno != ENOENT))
  114.     {
  115.       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
  116.    current_filename, strerror(errno));
  117.       return 0;
  118.     }
  119. #endif
  120.   plp=pathlist;
  121.   if (name[0] != PATH_SEP)
  122.     while (plp)  /* Try along the path then */
  123.       {
  124. *current_filename=0;
  125. l=strlen(plp->path);
  126. if(l)
  127.   {
  128.     strcpy(current_filename, plp->path);
  129.     if(current_filename[l-1]!=PATH_SEP)
  130.       strcat(current_filename, PATH_STRING);
  131.   }
  132. strcat(current_filename, name);
  133. ctl->cmsg(CMSG_INFO, VERB_DEBUG, "Trying to open %s", current_filename);
  134. if ((fp=try_to_open(current_filename, decompress, noise_mode)))
  135.   return fp;
  136. #ifdef ENOENT
  137. if (noise_mode && (errno != ENOENT))
  138.   {
  139.     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", 
  140.  current_filename, strerror(errno));
  141.     return 0;
  142.   }
  143. #endif
  144. plp=plp->next;
  145.       }
  146.   
  147.   /* Nothing could be opened. */
  148.   *current_filename=0;
  149.   
  150.   if (noise_mode>=2)
  151.     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", name, strerror(errno));
  152.   
  153.   return 0;
  154. }
  155. /* This closes files opened with open_file */
  156. void close_file(FILE *fp)
  157. {
  158. #ifdef DECOMPRESSOR_LIST
  159.   if (pclose(fp)) /* Any better ideas? */
  160. #endif
  161.     fclose(fp);
  162. }
  163. /* This is meant for skipping a few bytes in a file or fifo. */
  164. void skip(FILE *fp, size_t len)
  165. {
  166.   size_t c;
  167.   char tmp[PATH_MAX];
  168.   while (len>0)
  169.     {
  170.       c=len;
  171.       if (c>PATH_MAX) c=PATH_MAX;
  172.       len-=c;
  173.       if (c!=fread(tmp, 1, c, fp))
  174. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: skip: %s",
  175.      current_filename, strerror(errno));
  176.     }
  177. }
  178. /* This'll allocate memory or die. */
  179. void *safe_malloc(size_t count)
  180. {
  181.   void *p;
  182.   if (count > (1<<21))
  183.     {
  184.       ctl->cmsg(CMSG_FATAL, VERB_NORMAL, 
  185.    "Strange, I feel like allocating %d bytes. This must be a bug.",
  186.    count);
  187.     }
  188.   else if ((p=malloc(count)))
  189.     return p;
  190.   else
  191.     ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Sorry. Couldn't malloc %d bytes.", count);
  192.   ctl->close();
  193.   exit(10);
  194.   return(NULL);
  195. }
  196. /* This adds a directory to the path list */
  197. void add_to_pathlist(const char *s)
  198. {
  199.   PathList *plp=safe_malloc(sizeof(PathList));
  200.   strcpy((plp->path=safe_malloc(strlen(s)+1)),s);
  201.   plp->next=pathlist;
  202.   pathlist=plp;
  203. }
  204. /* Free memory associated to path list */
  205. void free_pathlist(void)
  206. {
  207.   PathList *plp, *next_plp;
  208.   plp = pathlist;
  209.   while (plp) {
  210.     if (plp->path) {
  211.       free(plp->path);
  212.       plp->path=NULL;
  213.     }
  214.     next_plp = plp->next;
  215.     free(plp);
  216.     plp = next_plp;
  217.   }
  218.   pathlist = NULL;
  219. }