home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / SMAILSRC.ZIP / SMAIL.ZIP / GETPATH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-05  |  3.0 KB  |  129 lines

  1. /*
  2. **  Patched for MS-DOS compatibility by Stephen Trier
  3. **  March, April and May, 1990.  This file is in the
  4. **  public domain.
  5. */
  6.  
  7. #ifndef lint
  8. static char     *sccsid="@(#)getpath.c    2.5 (smail) 9/15/87";
  9. #endif
  10.  
  11. # include    <stdio.h>
  12. # include    <sys/types.h>
  13. # include    <ctype.h>
  14. # include    "defs.h"
  15.  
  16. extern enum edebug debug;    /* how verbose we are         */ 
  17. extern char *pathfile;        /* location of path database    */
  18.  
  19. /*
  20. **
  21. ** getpath(): look up key in ascii sorted path database.
  22. **
  23. */
  24.  
  25. getpath( key, path , cost)
  26. char *key;        /* what we are looking for */
  27. char *path;        /* where the path results go */
  28. int *cost;        /* where the cost results go */
  29. {
  30.     long pos, middle, hi, lo;
  31.     static long pathlength = 0;
  32.     register char *s;
  33.     int c;
  34.     static FILE *file;
  35.     int flag;
  36.  
  37. DEBUG("getpath: looking for '%s'\n", key);
  38.  
  39.     if(pathlength == 0) {    /* open file on first use */
  40. #ifndef MSDOS
  41.         if((file = fopen(pathfile, "r")) == NULL) {
  42. #else
  43.         /*
  44.          *  All of the MS-DOS modifications in this section
  45.          *  deal with the MS-DOS \r\n line-ending vs. the UNIX
  46.          *  \n-only newline.  The solution is to read the file
  47.          *  in binary mode, and then deal with special characters
  48.          *  like ^Z as special cases. -SCT
  49.          */
  50.         if((file = fopen(pathfile, "rb")) == NULL) {
  51. #endif
  52.             (void) printf("can't access %s.\n", pathfile);
  53.             pathlength = -1;
  54.         } else {
  55.             (void) fseek(file, 0L, 2);    /* find length */
  56.             pathlength = ftell(file);
  57.         }
  58.     }
  59.     if( pathlength == -1 )
  60.         return( EX_OSFILE );
  61.  
  62.     lo = 0;
  63.     hi = pathlength;
  64.     (void) strcpy( path, key );
  65.     (void) strcat( path, "\t" );
  66. /*
  67. ** "Binary search routines are never written right the first time around."
  68. ** - Robert G. Sheldon.
  69. */
  70.     for( ;; ) {
  71.         pos = middle = ( hi+lo+1 )/2;
  72.         (void) fseek(file, pos, 0);    /* find midpoint */
  73.         if(pos != 0)
  74.             while(((c = getc(file)) != EOF) && (c != '\n'))
  75.                 ;    /* go to beginning of next line */
  76.         if(c == EOF) {
  77.             return(EX_NOHOST);
  78.         }
  79.         for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */
  80.             if( *s == '\0' ) {
  81.                 goto solved;
  82.             }
  83.             if((c = getc(file)) == EOF) {
  84.                 return(EX_NOHOST);
  85.             }
  86.             flag = lower(c) - lower(*s);
  87. #ifdef MSDOS
  88.             if (c == '\x1A')    /* Deal with ^Z  -SCT */
  89.                 c = EOF;
  90. #endif
  91.         }
  92.         if(lo >= middle) {        /* failure? */
  93.             return(EX_NOHOST);
  94.         }
  95.         if((c != EOF) && (flag < 0)) {    /* close window */
  96.             lo = middle;
  97.         } else {
  98.             hi = middle - 1;
  99.         }
  100.     }
  101. /* 
  102. ** Now just copy the result.
  103. */
  104. solved:
  105. #ifndef MSDOS
  106.     while(((c  = getc(file)) != EOF) && (c != '\t') && (c != '\n')) {
  107. #else
  108.     while(((c  = getc(file)) != EOF) && (c != '\t') && (c != '\n')
  109.          && (c != '\x0D')) {
  110. #endif
  111.         *path++ = c;
  112.     }
  113.     *path = '\0';
  114. /*
  115. ** See if the next field on the line is numeric.
  116. ** If so, use it as the cost for the route.
  117. */
  118.     if(c == '\t') {
  119.         int tcost = -1;
  120.         while(((c = getc(file)) != EOF) && isdigit(c)) {
  121.             if(tcost < 0) tcost = 0;
  122.             tcost *= 10;
  123.             tcost += c - '0';
  124.         }
  125.         if(tcost >= 0) *cost = tcost;
  126.     }
  127.     return (EX_OK);
  128. }
  129.