home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / gopherd / dedot.c < prev    next >
C/C++ Source or Header  |  1992-04-08  |  3KB  |  107 lines

  1. #include <stdio.h>
  2.  
  3. /*
  4. ** These routines can be used to remove ../ and ./ entries from
  5. ** pathnames.  These routines do it radically, without any attempt
  6. ** at all at interpretation.  This is okay for a gopher server,
  7. ** because clients aren't supposed to ask for .. or . in a request.
  8. **
  9. ** We want to do this so that we can avoid the chroot(), so that we
  10. ** can have symbolic links under the gopher directory to other things
  11. ** (like man pages for example) outside our structure, and still be
  12. ** safe.  Unless of course someone makes a link to / or somewhere silly.
  13. **
  14. ** dedot1 will remove dots from one string in place, dedot2 will copy
  15. ** one to the other, removing in the process - the src and dst can be
  16. ** the same.  dedot1 can use this to advantage - it checks first if
  17. ** things have to be removed, and calls dedot2 if necessary.  This
  18. ** is a slight advantage because in most cases we won't do anything,
  19. ** and we save the expense of copying data back and forth.  This
  20. ** seems to save almost half the time (very loose testing though).
  21. **
  22. ** John Sellens jmsellens@watdragon.waterloo.edu
  23. */
  24.  
  25. /* If DOSINGLE is defined, references to '.' are also removed */
  26. #define DOSINGLE
  27.  
  28.  
  29. dedot1( src )
  30. char *src;
  31. {
  32.     if ( *src == '.' ) {
  33.     if (
  34. #ifdef DOSINGLE
  35.     src[1] == '\0' || src[1] == '/' ||
  36. #endif
  37.     ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) {
  38.         dedot2( src, src );
  39.         return;
  40.     }
  41.     }
  42.     while ( *src ) {
  43.     if ( *src++ == '/' ) {
  44.         if ( *src == '.' ) {
  45.         if (
  46. #ifdef DOSINGLE
  47.         src[1] == '\0' || src[1] == '/' ||
  48. #endif
  49.         ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) {
  50.             dedot2( src, src );
  51.             return;
  52.         }
  53.         }
  54.     }
  55.     }
  56.     return;
  57. }
  58.  
  59. /* copy src to dst, blindly removing (not interpreting) ./ and ../ */
  60. dedot2( src, dst )
  61. char *src;
  62. char *dst;
  63. {
  64.     /*
  65.     ** We either have /, a filename, ./ or ../
  66.     */
  67.  
  68.     while ( *src ) {
  69.     switch ( *src ) {
  70.         case '/':
  71.         /* copy it, and skip any extras e.g. /a///b */
  72.         *dst++ = *src++;
  73.         while ( *src == '/' )
  74.             src++;
  75.         break;
  76.         case '.':
  77. #ifdef DOSINGLE
  78.         /* don't forget about trailing . and .. */
  79.         if ( src[1] == '/'  ) {        /* ./ */
  80.             src += 2;
  81.             break;
  82.         }
  83.         if ( src[1] == '\0'  ) {    /* .\0 */
  84.             src += 1;    /* only 1 so we don't fall off the end */
  85.             break;
  86.         }
  87. #endif
  88.         if ( src[1] == '.' && src[2] == '/' ) {        /* ../ */
  89.             src += 3;
  90.             break;
  91.         }
  92.         if ( src[1] == '.' && src[2] == '\0' ) {    /* .. */
  93.             src += 2;    /* don't fall off the end */
  94.             break;
  95.         }
  96.         /* must be a filename - fall through */
  97.         default:
  98.         /* must be filename - copy it over */
  99.         while ( *src != '\0' && *src != '/' )
  100.             *dst++ = *src++;
  101.         break;
  102.     }
  103.     }
  104.     /* and terminate it */
  105.     *dst = '\0';
  106. }
  107.