home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * lindner
- * 3.1.1.1
- * 1993/02/11 18:02:50
- * /home/mudhoney/GopherSrc/CVS/gopher+/gopherd/dedot.c,v
- * $Status: $
- *
- * Paul Lindner, University of Minnesota CIS.
- *
- * Copyright 1991, 1992 by the Regents of the University of Minnesota
- * see the file "Copyright" in the distribution for conditions of use.
- *********************************************************************
- * MODULE: dedot.c
- * See below.
- *********************************************************************
- * Revision History:
- * dedot.c,v
- * Revision 3.1.1.1 1993/02/11 18:02:50 lindner
- * Gopher+1.2beta release
- *
- * Revision 1.1 1992/12/10 23:13:27 lindner
- * gopher 1.1 release
- *
- *
- *********************************************************************/
-
-
- #include <stdio.h>
-
- /*
- ** These routines can be used to remove ../ and ./ entries from
- ** pathnames. These routines do it radically, without any attempt
- ** at all at interpretation. This is okay for a gopher server,
- ** because clients aren't supposed to ask for .. or . in a request.
- **
- ** We want to do this so that we can avoid the chroot(), so that we
- ** can have symbolic links under the gopher directory to other things
- ** (like man pages for example) outside our structure, and still be
- ** safe. Unless of course someone makes a link to / or somewhere silly.
- **
- ** dedot1 will remove dots from one string in place, dedot2 will copy
- ** one to the other, removing in the process - the src and dst can be
- ** the same. dedot1 can use this to advantage - it checks first if
- ** things have to be removed, and calls dedot2 if necessary. This
- ** is a slight advantage because in most cases we won't do anything,
- ** and we save the expense of copying data back and forth. This
- ** seems to save almost half the time (very loose testing though).
- **
- ** John Sellens jmsellens@watdragon.waterloo.edu
- */
-
- /* If DOSINGLE is defined, references to '.' are also removed */
- #define DOSINGLE
-
- void dedot1();
- void dedot2();
-
- void
- dedot1( src )
- char *src;
- {
- if ( *src == '.' ) {
- if (
- #ifdef DOSINGLE
- src[1] == '\0' || src[1] == '/' ||
- #endif
- ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) {
- dedot2( src, src );
- return;
- }
- }
- while ( *src ) {
- if ( *src++ == '/' ) {
- if ( *src == '.' ) {
- if (
- #ifdef DOSINGLE
- src[1] == '\0' || src[1] == '/' ||
- #endif
- ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) {
- dedot2( src, src );
- return;
- }
- }
- }
- }
- return;
- }
-
- /* copy src to dst, blindly removing (not interpreting) ./ and ../ */
- void
- dedot2( src, dst )
- char *src;
- char *dst;
- {
- /*
- ** We either have /, a filename, ./ or ../
- */
-
- while ( *src ) {
- switch ( *src ) {
- case '/':
- /* copy it, and skip any extras e.g. /a///b */
- *dst++ = *src++;
- while ( *src == '/' )
- src++;
- break;
- case '.':
- #ifdef DOSINGLE
- /* don't forget about trailing . and .. */
- if ( src[1] == '/' ) { /* ./ */
- src += 2;
- break;
- }
- if ( src[1] == '\0' ) { /* .\0 */
- src += 1; /* only 1 so we don't fall off the end */
- break;
- }
- #endif
- if ( src[1] == '.' && src[2] == '/' ) { /* ../ */
- src += 3;
- break;
- }
- if ( src[1] == '.' && src[2] == '\0' ) { /* .. */
- src += 2; /* don't fall off the end */
- break;
- }
- /* must be a filename - fall through */
- default:
- /* must be filename - copy it over */
- while ( *src != '\0' && *src != '/' )
- *dst++ = *src++;
- break;
- }
- }
- /* and terminate it */
- *dst = '\0';
- }
-