home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / gopherd / dedot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-11  |  3.5 KB  |  138 lines

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