Annotation of embedaddon/thttpd/extras/makeweb.c, revision 1.1
1.1 ! misho 1: /* makeweb.c - let a user create a web subdirectory
! 2: **
! 3: ** Copyright © 1995 by Jef Poskanzer <jef@mail.acme.com>.
! 4: ** All rights reserved.
! 5: **
! 6: ** Redistribution and use in source and binary forms, with or without
! 7: ** modification, are permitted provided that the following conditions
! 8: ** are met:
! 9: ** 1. Redistributions of source code must retain the above copyright
! 10: ** notice, this list of conditions and the following disclaimer.
! 11: ** 2. Redistributions in binary form must reproduce the above copyright
! 12: ** notice, this list of conditions and the following disclaimer in the
! 13: ** documentation and/or other materials provided with the distribution.
! 14: **
! 15: ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 16: ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 17: ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 18: ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 19: ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 20: ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 21: ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 23: ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 24: ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 25: ** SUCH DAMAGE.
! 26: */
! 27:
! 28: /* This is intended to be installed setgid to a group that has
! 29: ** write access to the system web directory. It allows any user
! 30: ** to create a subdirectory there. It also makes a symbolic link
! 31: ** in the user's home directory pointing at the new web subdir.
! 32: */
! 33:
! 34:
! 35: #include "../config.h"
! 36:
! 37: #include <stdlib.h>
! 38: #include <unistd.h>
! 39: #include <stdio.h>
! 40: #include <string.h>
! 41: #include <pwd.h>
! 42: #include <errno.h>
! 43: #include <sys/types.h>
! 44: #include <sys/stat.h>
! 45:
! 46:
! 47: #define LINK "public_html"
! 48:
! 49: static char* argv0;
! 50:
! 51:
! 52: static void
! 53: check_room( int size, int len )
! 54: {
! 55: if ( len > size )
! 56: {
! 57: (void) fprintf( stderr, "%s: internal error, out of room\n", argv0 );
! 58: exit( 1 );
! 59: }
! 60: }
! 61:
! 62:
! 63: static void
! 64: end_with_slash( char* str )
! 65: {
! 66: if ( str[strlen( str ) - 1] != '/' )
! 67: (void) strcat( str, "/" );
! 68: }
! 69:
! 70:
! 71: static void
! 72: check_dir( char* dirname, uid_t uid, gid_t gid )
! 73: {
! 74: struct stat sb;
! 75:
! 76: /* Check the directory. */
! 77: if ( stat( dirname, &sb ) < 0 )
! 78: {
! 79: if ( errno != ENOENT )
! 80: {
! 81: perror( dirname );
! 82: exit( 1 );
! 83: }
! 84: /* Doesn't exist. Try to make it. */
! 85: if ( mkdir( dirname, 0755 ) < 0 )
! 86: {
! 87: if ( errno == ENOENT )
! 88: (void) printf( "\
! 89: Some part of the path %s does not exist.\n\
! 90: This is probably a configuration error.\n", dirname );
! 91: else
! 92: perror( dirname );
! 93: exit( 1 );
! 94: }
! 95: (void) printf( "Created web directory %s\n", dirname );
! 96: /* Try to change the group of the new dir to the user's group. */
! 97: (void) chown( dirname, -1, gid );
! 98: }
! 99: else
! 100: {
! 101: /* The directory already exists. Well, check that it is in
! 102: ** fact a directory.
! 103: */
! 104: if ( ! S_ISDIR( sb.st_mode ) )
! 105: {
! 106: (void) printf(
! 107: "%s already exists but is not a directory!\n", dirname );
! 108: exit( 1 );
! 109: }
! 110: if ( sb.st_uid != uid )
! 111: {
! 112: (void) printf(
! 113: "%s already exists but you don't own it!\n", dirname );
! 114: exit( 1 );
! 115: }
! 116: (void) printf( "Web directory %s already existed.\n", dirname );
! 117: }
! 118: }
! 119:
! 120:
! 121: int
! 122: main( int argc, char** argv )
! 123: {
! 124: char* webdir;
! 125: char* prefix;
! 126: struct passwd* pwd;
! 127: char* username;
! 128: char* homedir;
! 129: char dirname[5000];
! 130: char linkname[5000];
! 131: char linkbuf[5000];
! 132: struct stat sb;
! 133:
! 134: argv0 = argv[0];
! 135: if ( argc != 1 )
! 136: {
! 137: (void) fprintf( stderr, "usage: %s\n", argv0 );
! 138: exit( 1 );
! 139: }
! 140:
! 141: pwd = getpwuid( getuid() );
! 142: if ( pwd == (struct passwd*) 0 )
! 143: {
! 144: (void) fprintf( stderr, "%s: can't find your username\n", argv0 );
! 145: exit( 1 );
! 146: }
! 147: username = pwd->pw_name;
! 148: homedir = pwd->pw_dir;
! 149:
! 150: #ifdef TILDE_MAP_2
! 151:
! 152: /* All we have to do for the TILDE_MAP_2 case is make sure there's
! 153: ** a public_html subdirectory.
! 154: */
! 155: check_room(
! 156: sizeof(dirname), strlen( homedir ) + strlen( TILDE_MAP_2 ) + 2 );
! 157: (void) strcpy( dirname, homedir );
! 158: end_with_slash( dirname );
! 159: (void) strcat( dirname, TILDE_MAP_2 );
! 160:
! 161: check_dir( dirname, pwd->pw_uid, pwd->pw_gid );
! 162:
! 163: #else /* TILDE_MAP_2 */
! 164:
! 165: /* Gather the pieces. */
! 166: webdir = WEBDIR;
! 167: #ifdef TILDE_MAP_1
! 168: prefix = TILDE_MAP_1;
! 169: #else /* TILDE_MAP_1 */
! 170: prefix = "";
! 171: #endif /* TILDE_MAP_1 */
! 172:
! 173: /* Assemble the directory name. Be paranoid cause we're sgid. */
! 174: check_room(
! 175: sizeof(dirname),
! 176: strlen( webdir ) + strlen( prefix ) + strlen( username ) + 3 );
! 177: (void) strcpy( dirname, webdir );
! 178: end_with_slash( dirname );
! 179: if ( strlen( prefix ) != 0 )
! 180: {
! 181: (void) strcat( dirname, prefix );
! 182: end_with_slash( dirname );
! 183: }
! 184: (void) strcat( dirname, username );
! 185:
! 186: /* Assemble the link name. */
! 187: check_room( sizeof(linkname), strlen( homedir ) + strlen( LINK ) + 2 );
! 188: (void) strcpy( linkname, homedir );
! 189: end_with_slash( linkname );
! 190: (void) strcat( linkname, LINK );
! 191:
! 192: check_dir( dirname, pwd->pw_uid, pwd->pw_gid );
! 193:
! 194: /* Check the symlink. */
! 195: try_link_again: ;
! 196: if ( lstat( linkname, &sb ) < 0 )
! 197: {
! 198: if ( errno != ENOENT )
! 199: {
! 200: perror( linkname );
! 201: exit( 1 );
! 202: }
! 203: /* Doesn't exist. Try to make it. */
! 204: if ( symlink( dirname, linkname ) < 0 )
! 205: {
! 206: if ( errno == ENOENT )
! 207: (void) printf( "\
! 208: Some part of the path %s does not exist.\n\
! 209: This is probably a configuration error.\n", linkname );
! 210: else
! 211: perror( linkname );
! 212: exit( 1 );
! 213: }
! 214: (void) printf( "Created symbolic link %s\n", linkname );
! 215: }
! 216: else
! 217: {
! 218: /* The link already exists. Well, check that it is in
! 219: ** fact a link.
! 220: */
! 221: if ( ! S_ISLNK( sb.st_mode ) )
! 222: {
! 223: (void) printf( "\
! 224: %s already exists but is not a\n\
! 225: symbolic link! Perhaps you have a real web subdirectory in your\n\
! 226: home dir from a previous web server configuration? You may have\n\
! 227: to rename it, run %s again, and then copy in the old\n\
! 228: contents.\n", linkname, argv0 );
! 229: exit( 1 );
! 230: }
! 231: /* Check the existing link's contents. */
! 232: if ( readlink( linkname, linkbuf, sizeof(linkbuf) ) < 0 )
! 233: {
! 234: perror( linkname );
! 235: exit( 1 );
! 236: }
! 237: if ( strcmp( dirname, linkbuf ) == 0 )
! 238: (void) printf( "Symbolic link %s already existed.\n", linkname );
! 239: else
! 240: {
! 241: (void) printf( "\
! 242: Symbolic link %s already existed\n\
! 243: but it points to the wrong place! Attempting to remove and\n\
! 244: recreate it.\n", linkname );
! 245: if ( unlink( linkname ) < 0 )
! 246: {
! 247: perror( linkname );
! 248: exit( 1 );
! 249: }
! 250: goto try_link_again;
! 251: }
! 252: }
! 253: #endif /* TILDE_MAP_2 */
! 254:
! 255: exit( 0 );
! 256: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>