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

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