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