home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / t / tex / !dvips / Documents / Fonts / Source / c / search < prev    next >
Encoding:
Text File  |  1994-10-23  |  13.9 KB  |  513 lines

  1. /*
  2.  *   The search routine takes a directory list, separated by PATHSEP, and
  3.  *   tries to open a file.  Null directory components indicate current
  4.  *   directory. if the file SUBDIR exists and the file is a font file,
  5.  *   it checks for the file in a subdirectory named the same as the font name.
  6.  *   Returns the open file descriptor if ok, else NULL.
  7.  */
  8. #include "dvips.h" /* The copyright notice in that file is included too! */
  9. #include <ctype.h>
  10. #ifdef OS2
  11. #include <stdlib.h>
  12. FILE *fat_fopen();
  13. #endif
  14.  
  15. #if defined(SYSV) || defined(VMS) || defined(__THINK__) || defined(MSDOS) || defined(OS2) || defined(RISCOS)
  16. #define MAXPATHLEN (256)
  17. #else
  18. #include <sys/param.h>          /* for MAXPATHLEN */
  19. #endif
  20. #if !defined(MSDOS) && !defined(OS2)
  21. #if !defined(VMS) && !defined(MVSXA) && !defined(__THINK__) && !defined(RISCOS)
  22. #ifndef VMCMS /* IBM: VM/CMS */
  23. #include <pwd.h>
  24. #endif  /* IBM: VM/CMS */
  25. #endif
  26. #endif
  27. #ifdef RISCOS
  28. #ifndef IGNORE_CWD
  29. extern char* fullpath ;
  30. #endif
  31. #endif
  32. /*
  33.  *
  34.  *   We hope MAXPATHLEN is enough -- only rudimentary checking is done!
  35.  */
  36.  
  37. #ifdef DEBUG
  38. extern integer debug_flag;
  39. #endif  /* DEBUG */
  40. extern char *mfmode ;
  41. extern int actualdpi ;
  42. char realnameoffile[MAXPATHLEN] ;
  43. FILE *
  44. search(path, file, mode)
  45.         char *path, *file, *mode ;
  46. {
  47.    extern char *getenv(), *newstring() ;
  48.    register char *nam ;                 /* index into fname */
  49.    register FILE *fd ;                  /* file desc of file */
  50.    char fname[MAXPATHLEN] ;             /* to store file name */
  51.    static char *home = 0 ;              /* home is where the heart is */
  52. #ifdef MVSXA
  53. char fname_safe[256];
  54. register int i, firstext, lastext, lastchar;
  55. #endif
  56. #ifdef VMCMS /* IBM: VM/CMS - we don't have paths or dirsep's but we strip off
  57.                              filename if there is a Unix path dirsep    */
  58.    register char *lastdirsep ;
  59.    lastdirsep = strrchr(file, '/') ;
  60.    if ( NULL != lastdirsep ) file = lastdirsep + 1 ;
  61.    if ((fd=fopen(file,mode)) != NULL) {
  62.       return(fd) ;
  63.    } else {
  64.       return(NULL) ;
  65.    }
  66. #else
  67. #ifdef RISCOS /* With RISC OS filenames we shouldn't search the paths if it
  68.                   start with '$' (and perhaps '&' and '@') or contain at least one ':' */
  69.    if (*file == '$' || *file == '&' || *file == '@' || strrchr(file,':')) {
  70.       if ((fd=fopen(file,mode)) != NULL) {
  71.          strcpy(realnameoffile, file) ;
  72.          setvbuf(fd,0,_IOFBF,4096*32) ;
  73.          return(fd) ;
  74.       } else
  75.          return(NULL) ;
  76.    }
  77. #else
  78.    if (*file == DIRSEP) {               /* if full path name */
  79.       if ((fd=fopen(file,mode)) != NULL) {
  80.          strcpy(realnameoffile, file) ;
  81.          return(fd) ;
  82.       } else
  83.          return(NULL) ;
  84.    }
  85. #endif
  86. #endif   /* IBM: VM/CMS */
  87.  
  88. #if defined MSDOS || defined OS2
  89.    if ( isalpha(file[0]) && file[1]==':' ) {   /* if full path name */
  90.       if ((fd=fopen(file,mode)) != NULL)
  91.          return(fd) ;
  92.       else
  93.          return(NULL) ;
  94.    }
  95. #endif
  96.  
  97.    do {
  98.       /* copy the current directory into fname */
  99.       nam = fname;
  100.       /* copy till PATHSEP */
  101. #ifndef RISCOS /* In RISCOS a '~' is just a normal valid filename
  102.                   character, and the home directory symbol '&' is
  103.                   resolved by RISC OS itself. */
  104.       if (*path == '~') {
  105.          char *p = nam ;
  106.          path++ ;
  107.          while (*path && *path != PATHSEP && *path != DIRSEP)
  108.             *p++ = *path++ ;
  109.          *p = 0 ;
  110.          if (*nam == 0) {
  111.             if (home == 0) {
  112.                if (0 != (home = getenv("HOME")))
  113.                   home = newstring(home) ;
  114.                else
  115.                   home = "." ;
  116.             }
  117.             strcpy(fname, home) ;
  118.          } else {
  119. #if defined MSDOS || defined OS2
  120.             error("! ~username in path???") ;
  121. #else
  122. #ifdef VMS
  123.             error("! ~username in path???") ;
  124. #else
  125. #ifdef VMCMS  /* IBM: VM/CMS */
  126.             error("! ~username in path???") ;
  127. #else
  128. #ifdef MVSXA  /* IBM: MVS/XA */
  129.             error("! ~username in path???") ;
  130. #else
  131. #ifdef __THINK__
  132.             error("! ~username in path???") ;
  133. #else
  134.             struct passwd *pw = getpwnam(fname) ;
  135.             if (pw)
  136.                strcpy(fname, pw->pw_dir) ;
  137.             else
  138.                error("no such user") ;
  139. #endif
  140. #endif  /* IBM: VM/CMS */
  141. #endif
  142. #endif
  143. #endif
  144.          }
  145.          nam = fname + strlen(fname) ;
  146.       }
  147. #endif
  148.       while (*path != PATHSEP && *path) *nam++ = *path++;
  149.       *nam = 0 ;
  150. #ifndef VMS
  151. #ifndef __THINK__
  152. #ifdef RISCOS
  153.       if (nam == fname)   /* null component is current dir */
  154. #ifdef IGNORE_CWD
  155.          *nam++ = '@' ;
  156. #else
  157.          if (!fullpath)
  158.             *nam++ = '@' ;
  159.          else {
  160.             strcpy(nam,fullpath) ;
  161.             while (*nam++) ;
  162.             nam-- ;
  163.          }
  164. #endif
  165. #else
  166.       if (nam == fname) *nam++ = '.';   /* null component is current dir */
  167. #endif
  168.       if (*file != '\0') {
  169. #ifdef RISCOS
  170.          if ((nam != fname) && *(nam-1) != DIRSEP && *(nam-1) != ':')
  171. #else
  172.          if ((nam != fname) && *(nam-1) != DIRSEP) /* GNW 1992.07.09 */
  173. #endif
  174.             *nam++ = DIRSEP;                    /* add separator */
  175.          (void)strcpy(nam,file);                /* tack the file on */
  176.       }
  177.       else
  178.          *nam = '\0' ;
  179. #else
  180.       (void)strcpy(nam,file);                   /* tack the file on */
  181. #endif
  182. #else
  183.       (void)strcpy(nam,file);                   /* tack the file on */
  184. #endif
  185. #ifdef MVSXA
  186. nam = fname;
  187. if (strchr(nam,'=') != NULL) {
  188.    (void) strcpy(fname_safe,fname);  /* save fname */
  189.    firstext = strchr(nam, '=') - nam + 2;
  190.    lastext = strrchr(nam, '.') - nam + 1;
  191.    lastchar  = strlen(nam) - 1;
  192.  
  193.    (void) strcpy(fname,"dd:");  /* initialize fname */
  194.    nam=&fname[3];
  195.    for (i=lastext; i<=lastchar; i++) *nam++ = fname_safe[i] ;
  196.            *nam++  = '(' ;
  197.    for (i=firstext; i<lastext-1; i++) *nam++ = fname_safe[i] ;
  198.            *nam++  = ')' ;
  199.            *nam++  = 0   ;
  200.    }
  201.    else {
  202.       if (fname[0] == '/') {
  203.          fname[0] = '\'';
  204.          strcat(&fname[strlen(fname)],"\'");
  205.       }
  206.       if (fname[0] == '.') fname[0] = ' ';
  207.       if (fname[1] == '.') fname[1] = ' ';
  208.    }
  209. #endif
  210.  
  211.       /* belated check -- bah! */
  212.       if ((nam - fname) + strlen(file) + 1 > MAXPATHLEN)
  213.          error("! overran allocated storage in search()");
  214.  
  215. #ifdef DEBUG
  216.       if (dd(D_PATHS))
  217.          (void)fprintf(stderr,"search: Trying to open %s\n", fname) ;
  218. #endif
  219.       if ((fd=fopen(fname,mode)) != NULL) {
  220.          strcpy(realnameoffile, fname) ;
  221.          return(fd);
  222.       }
  223.  
  224.    /* skip over PATHSEP and try again */
  225.    } while (*(path++));
  226.  
  227.    return(NULL);
  228.  
  229. }               /* end search */
  230.  
  231. FILE *
  232. pksearch(path, file, mode, n, dpi, vdpi)
  233.         char *path, *file, *mode ;
  234.     char *n ;
  235.     halfword dpi, vdpi ;
  236. {
  237.    extern char *getenv(), *newstring() ;
  238.    register char *nam ;                 /* index into fname */
  239.    register FILE *fd ;                  /* file desc of file */
  240.    char fname[MAXPATHLEN] ;             /* to store file name */
  241.    static char *home = 0 ;              /* home is where the heart is */
  242.    int sub ;
  243.  
  244. #ifdef RISCOS /* With RISC OS filenames we shouldn't search the paths if it
  245.                   start with '$' (and perhaps '&' and '@') or contain at least one ':' */
  246.    if (*file == '$' || *file == '&' || *file == '@' || strrchr(file,':')) {
  247.       if ((fd=fopen(file,mode)) != NULL) {
  248.          strcpy(realnameoffile, file) ;
  249.          setvbuf(fd,0,_IOFBF,4096*32) ;
  250.          return(fd) ;
  251.       } else
  252.          return(NULL) ;
  253.    }
  254. #else
  255.    if (*file == DIRSEP) {               /* if full path name */
  256.       if ((fd=fopen(file,mode)) != NULL)
  257.          return(fd) ;
  258.       else
  259.          return(NULL) ;
  260.    }
  261. #endif
  262. #if defined MSDOS || defined OS2
  263.    if ( isalpha(file[0]) && file[1]==':' ) {  /* if full path name */
  264.       if ((fd=fopen(file,mode)) != NULL)
  265.          return(fd) ;
  266.       else
  267.          return(NULL) ;
  268.    }
  269. #endif
  270.    do {
  271.       /* copy the current directory into fname */
  272.       nam = fname;
  273.       sub = 0 ;
  274.       /* copy till PATHSEP */
  275. #ifndef RISCOS /* In RISCOS a '~' is just a normal valid filename
  276.                   character, and the home directory symbol '&' is
  277.                   resolved by RISC OS itself. */
  278.       if (*path == '~') {
  279.          char *p = nam ;
  280.          path++ ;
  281.          while (*path && *path != PATHSEP && *path != DIRSEP)
  282.             *p++ = *path++ ;
  283.          *p = 0 ;
  284.          if (*nam == 0) {
  285.             if (home == 0) {
  286.                if (0 != (home = getenv("HOME")))
  287.                   home = newstring(home) ;
  288.                else
  289.                   home = "." ;
  290.             }
  291.             strcpy(fname, home) ;
  292.          } else {
  293. #if defined MSDOS || defined OS2
  294.             error("! ~username in path???") ;
  295. #else
  296. #ifdef VMS
  297.             error("! ~username in path???") ;
  298. #else
  299. #ifdef VMCMS  /* IBM: VM/CMS */
  300.             error("! ~username in path???") ;
  301. #else
  302. #ifdef MVSXA  /* IBM: MVS/XA */
  303.             error("! ~username in path???") ;
  304. #else
  305. #ifdef __THINK__
  306.             error("! ~username in path???") ;
  307. #else
  308.             struct passwd *pw = getpwnam(fname) ;
  309.             if (pw)
  310.                strcpy(fname, pw->pw_dir) ;
  311.             else
  312.                error("no such user") ;
  313. #endif
  314. #endif /* IBM: VM/CMS */
  315. #endif
  316. #endif
  317. #endif
  318.          }
  319.          nam = fname + strlen(fname) ;
  320.       }
  321. #endif
  322.       /* copy till PATHSEP */
  323.       while (*path != PATHSEP && *path) {
  324.          if (*path == '%') {
  325.             sub = 1 ;
  326.             path++ ;
  327.             switch(*path) {
  328.                case 'b': sprintf(nam, "%d", actualdpi) ; break ;
  329.                case 'd': sprintf(nam, "%d", dpi) ; break ;
  330.                case 'f': strcpy(nam, n) ; break ;
  331.                case 'm': if (mfmode == 0)
  332.                             if (actualdpi == 300) mfmode = "imagen" ;
  333.                             else if (actualdpi == 400) mfmode = "nexthi" ;
  334.                             else if (actualdpi == 635) mfmode = "linolo" ;
  335.                             else if (actualdpi == 1270) mfmode = "linohi" ;
  336.                             else if (actualdpi == 2540) mfmode = "linosuper" ;
  337.                          if (mfmode == 0)
  338.                             error("! MF mode not set, but used in pk path") ;
  339.                          strcpy(nam, mfmode) ;
  340.                          break ;
  341.                case 'p': strcpy(nam, "pk") ; break ;
  342.                case '%': strcpy(nam, "%") ; break ;
  343.                default: error("! bad format character in pk path") ;
  344.             }
  345.             nam = fname + strlen(fname) ;
  346.             if (*path)
  347.                path++ ;
  348.          } else
  349.             *nam++ = *path++;
  350.       }
  351. #ifndef VMS
  352. #ifndef __THINK__
  353. #ifdef RISCOS
  354.       if (nam == fname)   /* null component is current dir */
  355. #ifdef IGNORE_CWD
  356.          *nam++ = '@' ;
  357. #else
  358.          if (!fullpath)
  359.             *nam++ = '@' ;
  360.          else {
  361.             strcpy(nam,fullpath) ;
  362.             while (*nam++) ;
  363.             nam-- ;
  364.          }
  365. #endif
  366. #else
  367.       if (nam == fname) *nam++ = '.';   /* null component is current dir */
  368. #endif
  369. #endif
  370. #endif /* VMS */
  371.       if (sub == 0 && *file) {
  372. #ifndef VMS
  373.          /* change suggested by MG */
  374. #ifdef RISCOS
  375.          if ((nam != fname) && *(nam-1) != DIRSEP && *(nam-1) != ':')
  376. #else
  377.          if ((nam != fname) && *(nam-1) != DIRSEP) /* GNW 1992.07.09 */
  378. #endif
  379.             *nam++ = DIRSEP ;
  380. #endif
  381.          strcpy(nam, file) ;
  382.       } else
  383.          *nam = 0 ;
  384.  
  385. #ifdef MVSXA   /* IBM: MVS/XA */
  386.       if (fname[0] == '/') {
  387.          fname[0] = '\'';
  388.          strcat(&fname[strlen(fname)],"\'");
  389.       }
  390.       if (fname[0] == '.') fname[0] = ' ';
  391.       if (fname[1] == '.') fname[1] = ' ';
  392. #endif         /* IBM: MVS/XA */
  393.       /* belated check -- bah! */
  394.       if (strlen(fname) + 1 > MAXPATHLEN)
  395.          error("! overran allocated storage in search()");
  396.  
  397. #ifdef DEBUG
  398.       if (dd(D_PATHS))
  399.          (void)fprintf(stderr,"pksearch: Trying to open %s\n", fname) ;
  400. #endif
  401.       if ((fd=fopen(fname,mode)) != NULL)
  402.          return(fd);
  403.  
  404.    /* skip over PATHSEP and try again */
  405.    } while (*(path++));
  406.  
  407.    return(NULL);
  408.  
  409. }               /* end search */
  410.  
  411. /* do we report file openings? */
  412.  
  413. #ifdef DEBUG
  414. #  ifdef fopen
  415. #    undef fopen
  416. #  endif
  417. #  ifdef VMCMS  /* IBM: VM/CMS */
  418. #    define fopen cmsfopen
  419. #  endif /* IBM: VM/CMS */
  420. FILE *my_real_fopen(n, t)
  421. register char *n, *t ;
  422. {
  423.    FILE *tf ;
  424.    if (dd(D_FILES)) {
  425.       fprintf(stderr, "<%s(%s)> ", n, t) ;
  426.       tf = fopen(n, t) ;
  427.       if (tf == 0)
  428.          fprintf(stderr, "failed\n") ;
  429.       else
  430.          fprintf(stderr, "succeeded\n") ;
  431.    } else
  432.       tf = fopen(n, t) ;
  433. #ifdef OS2
  434.    if (tf == (FILE *)NULL)
  435.      tf = fat_fopen(n, t); /* try again with filename truncated to 8.3 */
  436. #endif
  437.    return tf ;
  438. }
  439. #endif
  440.  
  441. #ifdef OS2
  442. /* truncate filename at end of fname to FAT filesystem 8.3 limit */
  443. /* if truncated, return fopen() with new name */
  444. FILE *fat_fopen(fname, t)
  445. char *fname, *t;
  446. {
  447.    char *np;    /* pointer to name within path */
  448.    char nbuf[13], *ns, *nd;
  449.    char n[MAXPATHLEN];
  450.    int ni, ne;
  451.    FILE *tf;
  452.    strcpy(n, fname);
  453.    for (ns=n; *ns; ns++) {
  454.       if (*ns=='/')
  455.          *ns=DIRSEP;
  456.    }
  457.    np = strrchr(n,DIRSEP);
  458.    if (np==(char *)NULL)
  459.       np = n;
  460.    else
  461.       np++;
  462.    /* fail if it contains more than one '.' */
  463.    ni = 0;
  464.    for (ns=np; *ns; ns++) {
  465.       if (*ns=='.')
  466.          ni++;
  467.    }
  468.    if (ni>1)
  469.       return (FILE *)NULL;
  470.    /* copy it to nbuf, truncating to 8.3 */
  471.    ns = np;
  472.    nd = nbuf;
  473.    ni = 0;
  474.    while ((*ns!='.') && (*ns) && (ni<8)) {
  475.       *nd++ = *ns++;
  476.       ni++;
  477.    }
  478.    while ((*ns!='.') && (*ns)) {
  479.       ns++;
  480.       ni++;
  481.    }
  482.    ne = 0;
  483.    if (*ns=='.') {
  484.       *nd++ = *ns++;
  485.       while ((*ns!='.') && (*ns) && (ne<3)) {
  486.          *nd++ = *ns++;
  487.          ne++;
  488.       }
  489.       while (*ns) {
  490.          ns++;
  491.          ne++;
  492.       }
  493.    }
  494.    *nd++='\0';
  495.    if ((ni>8) || (ne>3)) {
  496.       strcpy(np,nbuf);
  497.       /* now code copied from my_real_fopen() */
  498.       if (dd(D_FILES)) {
  499.          fprintf(stderr, "<%s(%s)> ", n, t) ;
  500.          tf = fopen(n, t) ;
  501.          if (tf == 0)
  502.             fprintf(stderr, "failed\n") ;
  503.          else
  504.             fprintf(stderr, "succeeded\n") ;
  505.       }
  506.       else
  507.          tf = fopen(n, t) ;
  508.       return tf;
  509.    }
  510.    return (FILE *)NULL;
  511. }
  512. #endif
  513.