Subject: Shutting down your ftp server

From: Kent Landfield <[email-masked]>
Date: Tue, 4 Mar 1997 15:03:33 -0600 (CST)

I needed to shutdown my FTP server here and turn off service to the
virtual servers I manage.  I found that shutting down the ftp server
with ftpshut in a virtual setup was kludgey at best.  

What I've included in the shar file below is the source to ftpshut 
with modification and ftprestart (to allow easy restarting of the server).

ftpshut.c changes
------------------

The copy of ftpshut.c (taken from BETA-13) supports shutting down the 
server for both real users as well as guest accounts.  It also supports 
virtual FTP servers.

Configurations:
 - FTPD server setup with no anonymous ftp support and NO virtual servers
   setup then the changes to ftpshut have no effect.  The shutdown message
   file specified in the shutdown directive is created as before.

 - FTPD server setup WITH anonymous ftp support and NO virtual servers setup,
   ftpshut creates the shutdown message file at the location specified in
   the shutdown directive and also creates the message file in the anonymous
   FTP area.  This allows automated support for both real users and guest
   accounts.

 - FTPD server setup WITH anonymous ftp support and WITH virtual servers
   setup, ftpshut acts as above and additionally creates the shutdown
   message file in the virtual FTP directories specified in the ftpaccess
   file.  This allows shutdown support for virtual servers as well.

ftprestart removes the files put in place by ftpshut.

This is beta software and I'd appreciate any feedback.  I am not putting any
copyrights on this software and it can be used as you see fit.  Useful here...

			-Kent+
-- 
Kent Landfield                        Phone: 1-817-545-2502             
The Landfield Group                   FAX:   1-817-545-7650             
Email: [email-masked]             http://www.landfield.com/
Please send comp.sources.misc related mail to [email-masked].
Search the Usenet Hypertext FAQ Archive at http://www.landfield.com/faqs/
----------------- Cut here ---------------------
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1997-03-04 14:53 CST by <[email-masked]>.
# Source directory was `/src/cmd/wu-ftpd/wu-ftpd-2.4.2-beta-13/src'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   4421 -rw-r--r-- README
#   4010 -rw-r--r-- ftprestart.c
#  10032 -rw-r--r-- ftpshut.c
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh11075; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= README ==============
if test -f 'README' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'README' '(file already exists)'
else
  $echo 'x -' extracting 'README' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'README' &&
X                       Shutting Down Your FTP server 
X                       =============================
X
In order to support the proper shutting down of your server, you need to
assure that the shutdown message file is in both the real user and anonymous 
user ftp areas.  The location of the shutdown mesage file is specified in 
the ftpaccess file "shutdown" directive.
X
The problem is the supplied utility, 'ftpshut', only creates the message
file in the actual location as indicated in the shutdown directive.
X
In the INSTALL file of wu-ftpd 2.4.* it is recommended to create a link
in order for shutdown to work properly for real and anonymous user, e.g.
If you use 'ftpshut', it will create a message file at the location
specified in the ftpaccess shutdown directive.
X
When you are ready to remove the shutdown message file, you have to do so
manually.  (Ever had to go look in the ftpaccess file for its location 
because you forgot ...;-))
X
The following changes to 'ftpshut.c' and the new utility 'ftprestart' 
implement a means of shutting down the system that makes it convenient for 
the admin and does not require that you leave unresovled sybolic links 
scattered around your filesystems.
X
There are two files here, ftpshut and ftprestart. The copy of ftpshut.c
included below was originally taken from BETA-13.
X
PLEASE NOTE: In order to get the virtual FTP server support described below 
you need to specify -DVIRTUAL in the appropriate makefile for your system.
X
----------------------------------------------------------------------
ftpshut.c changes 
------------------
X
The copy of ftpshut.c supports shutting down the server for both
real users as well as guest accounts.  It also supports virtual
FTP servers. 
X
Configurations:
X - FTPD server setup with no anonymous ftp support and NO virtual servers 
X   setup then the changes to ftpshut have no effect.  The shutdown message
X   file specified in the shutdown directive is created as before.
X
X - FTPD server setup WITH anonymous ftp support and NO virtual servers setup,
X   ftpshut creates the shutdown message file at the location specified in 
X   the shutdown directive and also creates the message file in the anonymous 
X   FTP area.  This allows automated support for both real users and guest 
X   accounts.
X         
X - FTPD server setup WITH anonymous ftp support and WITH virtual servers 
X   setup, ftpshut acts as above and additionally creates the shutdown
X   message file in the virtual FTP directories specified in the ftpaccess
X   file.  This allows shutdown support for virtual servers as well.
X
------------------ Example segment ------------------
shutdown /etc/shutmsg
X
# Virtual Server at 10.10.10.2 (ftp.some.domain)
virtual 10.10.10.2 root    /servers/some.domain/ftp
virtual 10.10.10.2 banner  /servers/some.domain/ftp/etc/msgs/banner.msg
virtual 10.10.10.2 logfile /var/log/servers/some.domain/xferlog
X
X
# Virtual Server at 10.10.10.10 (ftp.someother.domain)
virtual 10.10.10.10 root    /servers/someother.domain/ftp
virtual 10.10.10.10 banner  /servers/someother.domain/ftp/etc/msgs/banner.msg
virtual 10.10.10.10 logfile /var/log/servers/someother.domain/xferlog
------------------ 
X
Shutdown message files are created at
X
X     /etc/shutmsg
X     /servers/some.domain/ftp/etc/shutmsg
X     /servers/someother.domain/ftp/etc/shutmsg
X
Each file contains the same information.
X
----------------------------------------------------------------------
ftprestart.c:
-------------
X
ftprestart is used when you are ready to re-enable your FTP server.
It does the opposite of ftpshut and removes shutdown message files
that were created by ftpshut.  It will remove the system-wide shutdown 
message file as well as the shutdown message files in the anonymous
ftp areas and any virtual ftp server areas.
X
Sample output:
X   ftprestart: /servers/some.domain/ftp/etc/shutmsg removed.
X   ftprestart: /servers/someother.domain/ftp/etc/shutmsg removed.
X   ftprestart: /etc/shutmsg removed.
X
These modifications are being contributed for potential inclusion in the
wu-ftpd baseline.  
X
---
Kent Landfield                        Phone: 1-817-545-2502             
The Landfield Group                   FAX:   1-817-545-7650             
Email: [email-masked]             http://www.landfield.com/
Please send comp.sources.misc related mail to [email-masked].
Search the Usenet Hypertext FAQ Archive at http://www.landfield.com/faqs/
SHAR_EOF
  $shar_touch -am 0304142897 'README' &&
  chmod 0644 'README' ||
  $echo 'restore of' 'README' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'README:' 'MD5 check failed'
a2fab41cac52a120636d5d6013d9bc5e  README
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'README'`"
    test 4421 -eq "$shar_count" ||
    $echo 'README:' 'original size' '4421,' 'current size' "$shar_count!"
  fi
fi
# ============= ftprestart.c ==============
if test -f 'ftprestart.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ftprestart.c' '(file already exists)'
else
  $echo 'x -' extracting 'ftprestart.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ftprestart.c' &&
/* ftprestart
**
** removes the ftpd shutdown files.
**
**  In the INSTALL file of wu-ftpd 2.4.* it is recommended to create a link
**  in order for shutdown to work properly for real and anonymous user, e.g.
**  If you use ftpshut, it will create a message file at the location
**  specified in the ftpaccess shutdown directive.
**  ln -s /etc/shutmsg  ~ftp/etc/shutmsg 
**  
**  When ftp service is to be restarted after an ftpshut, the shutdown 
**  message files must be removed. This program reads the ftpaccess
**  file and finds the location of the system shutdown file.  It
**  then proceeds to construct a path to the anonymous ftp area with
**  information found in the "ftp" account.  If virtual ftp servers
**  are enabled, the shutdown message files within those directories 
**  are also removed.
**  
*/
X
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <pwd.h>
X
#include "config.h"
#include "src/pathnames.h"
X
int
#ifdef __STDC__
remove_shutdown_file(char *path)
#else
remove_shutdown_file(path)
char *path;
#endif
{
X    struct stat stbuf;
X    int rc = 1;    /* guilty until proven innocent */
X
X    fprintf(stderr,"ftprestart: %s ",path);
X
X    if (stat(path, &stbuf) == 0) {
X        if ((rc = unlink(path)) == 0) 
X            fprintf(stderr,"removed.\n");
X        else 
X            perror(path);
X    }
X    else
X        fprintf(stderr,"does not exist.\n");
X
X    return(rc);
}
X
int main()
{
X    char *p;
X    char *cp = NULL;
X    char linebuf[BUFSIZ];
X    char shutmsg[256];
X    char anonpath[BUFSIZ];
X    FILE *accessfile;
X    struct passwd *pw;
X
#ifdef VIRTUAL 
X    char altmsgpath[BUFSIZ];
#endif 
X 
X    if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) {
X       if (errno != ENOENT)
X          perror("ftprestart: could not open() access file");
X          return(1);
X    }
X 
X    /* 
X    ** Search the access file for the 'shutdown' directive.
X    */
X 
X    while (fgets(linebuf,BUFSIZ,accessfile) != NULL) {
X       if (strncasecmp(linebuf,"shutdown",8)==0) {
X           (void) strtok(linebuf," \t");
X           cp=strncpy(shutmsg,strtok(NULL," \t"),sizeof(shutmsg));
X           shutmsg[sizeof(shutmsg)-1]='\0';
X           if ((p=strchr(cp,'\n'))!=NULL) 
X               *p='\0';
X       }
X    }
X 
X    if ( cp == NULL ) {
X       fprintf(stderr, "No shutdown file defined in ftpaccess file.\n");
X       fclose(accessfile);
X       return(1);
X    }
X 
X    /*
X    ** Get the location of the anonymous ftp area and check
X    ** to see if there is a file shutdown file there as well. 
X    ** If so, remove it.
X    */
X    if ((pw = getpwnam("ftp")) != NULL) {
X         sprintf(anonpath,"%s%s",pw->pw_dir,shutmsg);
X         (void) remove_shutdown_file(anonpath);
X    }
X
#ifdef VIRTUAL
X    /* 
X    ** Search the access file for virtual ftp servers. 
X    ** If found, check if there are links/shutdown 
X    ** message files files in the virtual server areas.   
X    ** If so, remove them.
X    */
X 
X    rewind(accessfile);
X 
X    while (fgets(linebuf,sizeof(linebuf)-1,accessfile) != NULL)  {
X       if (strncasecmp(linebuf,"virtual",7)==0) {
X           if ((p = strstr(linebuf,"root")) != NULL) {
X                p += 4;
X 
X               if ((cp = strchr(linebuf,'\n')) != NULL)
X                    *cp = '\0';
X
X               /* skip to the path */
X 
X               while (*p && isspace(*p)) 
X                    p++;
X               cp = p;
X               while (*p && isalnum(*p)) 
X                    p++;
X 
X              sprintf(altmsgpath,"%s%s",cp,shutmsg);
X
X              /*
X              ** Check to see if the virtual path created is
X              ** the base path specified in the "ftp" account
X              ** for anonymous ftp support.  If so, skip it.
X              */
X
X              if (strcmp(anonpath, altmsgpath))
X                  (void) remove_shutdown_file(altmsgpath);
X           }
X       }
X    }
#endif
X    fclose(accessfile);
X 
X    /*
X    ** Time to remove the system wide shutdown file.
X    */
X    return(remove_shutdown_file(shutmsg));
}
SHAR_EOF
  $shar_touch -am 0304145097 'ftprestart.c' &&
  chmod 0644 'ftprestart.c' ||
  $echo 'restore of' 'ftprestart.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ftprestart.c:' 'MD5 check failed'
2719ab8bc87ea26521ad64e645b5bf41  ftprestart.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ftprestart.c'`"
    test 4010 -eq "$shar_count" ||
    $echo 'ftprestart.c:' 'original size' '4010,' 'current size' "$shar_count!"
  fi
fi
# ============= ftpshut.c ==============
if test -f 'ftpshut.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'ftpshut.c' '(file already exists)'
else
  $echo 'x -' extracting 'ftpshut.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'ftpshut.c' &&
/* Copyright (c) 1993, 1994  Washington University in Saint Louis
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions are
X * met: 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer. 2.
X * Redistributions in binary form must reproduce the above copyright notice,
X * this list of conditions and the following disclaimer in the documentation
X * and/or other materials provided with the distribution. 3. All advertising
X * materials mentioning features or use of this software must display the
X * following acknowledgement: This product includes software developed by the
X * Washington University in Saint Louis and its contributors. 4. Neither the
X * name of the University nor the names of its contributors may be used to
X * endorse or promote products derived from this software without specific
X * prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
X * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
X * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
X * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASHINGTON
X * UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
X * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
X * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
X * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
X * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
X * POSSIBILITY OF SUCH DAMAGE.
X */
X
/* ftpshut 
X * ======= 
X * creates the ftpd shutdown file.
X */
X
#include "config.h"
X
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
X
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
X
#include "pathnames.h"
X
#define  WIDTH  70
X
int denyoffset = 10;            /* default deny time   */
int discoffset = 5;             /* default disc time   */
char *message = "System shutdown at %s";    /* default message     */
struct tm *tp;
X
extern version[];
X
int
#ifdef __STDC__
shutdown_msgfile(char *filename, char *buffer)
#else
shutdown_msgfile(filename, buffer)
char *filename;
char *buffer;
#endif
{
X    FILE *fp;
X
X    if ((fp = fopen(filename, "w")) == NULL )  {
X        perror("Couldn't open shutdown file");
X        return(1);
X    }
X
X    fprintf(fp, "%.4d %.2d %.2d %.2d %.2d %.4d %.4d\n",
X            (tp->tm_year) + 1900,
X            tp->tm_mon,
X            tp->tm_mday,
X            tp->tm_hour,
X            tp->tm_min,
X            denyoffset,
X            discoffset);
X    fprintf(fp, "%s\n", buffer);
X    fclose(fp);
X    return(0);
}
X
void
#ifdef __STDC__
massage(char *buf)
#else
massage(buf)
char *buf;
#endif
{
X    char *sp = NULL;
X    char *ptr;
X    int i = 0;
X    int j = 0;
X
X    ptr = buf;
X
X    while (*ptr++ != '\0') {
X        ++i;
X
X        /* if we have a space, keep track of where and at what "count" */
X
X        if (*ptr == ' ') {
X            sp = ptr;
X            j = i;
X        }
X        /* magic cookies... */
X
X        if (*ptr == '%') {
X            ++ptr;
X            switch (*ptr) {
X            case 'r':
X            case 's':
X            case 'd':
X            case 'T':
X                i = i + 24;
X                break;
X            case '\n':
X                i = 0;
X                break;
X            case 'C':
X            case 'R':
X            case 'L':
X            case 'U':
X                i = i + 10;
X                break;
X            case 'M':
X            case 'N':
X                i = i + 3;
X                break;
X            case '\0':
X                return;
X                break;
X            default:
X                i = i + 1;
X                break;
X            }
X        }
X        /* break up the long lines... */
X
X        if ((i >= WIDTH) && (sp != NULL)) {
X            *sp = '\n';
X            sp = NULL;
X            i = i - j;
X        }
X    }
}
X
int
#ifdef __STDC__
main(int argc, char **argv)
#else
main(argc,argv)
int argc;
char **argv;
#endif
{
X    time_t c_time;
X
X    char buf[BUFSIZ];
X
X    int c;
X    extern int optind;
X    extern char *optarg;
X
X    FILE *accessfile;
X    char *aclbuf,
X     *myaclbuf,
X     *crptr;
X    char *sp = NULL;
X    char linebuf[1024];
X    char shutmsg[BUFSIZ];
X    char anonpath[BUFSIZ];
X    struct stat finfo;
X    struct passwd *pwent;
X
#ifdef VIRTUAL
X    char altmsgpath[BUFSIZ];
X    char *cp;
#endif 
X
X    while ((c = getopt(argc, argv, "vl:d:")) != EOF) {
X        switch (c) {
X        case 'l':
X            denyoffset = atoi(optarg);
X            break;
X        case 'd':
X            discoffset = atoi(optarg);
X            break;
X		case 'v':
X			fprintf(stderr, "%s\n", version);
X			exit(0);
X        default:
X            fprintf(stderr,
X                "Usage: %s [-d min] [-l min] now [\"message\"]\n", argv[0]);
X            fprintf(stderr,
X                "       %s [-d min] [-l min] +dd [\"message\"]\n", argv[0]);
X            fprintf(stderr,
X               "       %s [-d min] [-l min] HHMM [\"message\"]\n", argv[0]);
X            exit(-1);
X        }
X    }
X
X    if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) {
X        if (errno != ENOENT)
X            perror("ftpshut: could not open() access file");
X        exit(1);
X    }
X    if (stat(_PATH_FTPACCESS, &finfo)) {
X        perror("ftpshut: could not stat() access file");
X        exit(1);
X    }
X    if (finfo.st_size == 0) {
X        printf("ftpshut: no service shutdown path defined\n");
X        exit(0);
X    } else {
X        if (!(aclbuf = (char *) malloc(finfo.st_size + 1))) {
X            perror("ftpcount: could not malloc aclbuf");
X            exit(1);
X        }
X        fread(aclbuf, finfo.st_size, 1, accessfile);
X        *(aclbuf + finfo.st_size) = '\0';
X    }
X
X    myaclbuf = aclbuf;
X    while (*myaclbuf != '\0') {
X        if (strncasecmp(myaclbuf, "shutdown", 8) == 0) {
X            for (crptr = myaclbuf; *crptr++ != '\n';) ;
X            *--crptr = '\0';
X            strcpy(linebuf, myaclbuf);
X            *crptr = '\n';
X            (void) strtok(linebuf, " \t");  /* returns "shutdown" */
X            sp = strtok(NULL, " \t");   /* returns shutdown path */
X            strcpy(shutmsg,sp);    /* save for future use */
X        }
X        while (*myaclbuf && *myaclbuf++ != '\n') ;
X    }
X
X    /* three cases 
X     * -- now 
X     * -- +ddd 
X     * -- HHMM 
X     */
X
X    c = -1;
X
X    if (optind < argc) {
X        if (!strcasecmp(argv[optind], "now")) {
X            c_time = time(0);
X            tp = localtime(&c_time);
X        } else if ((*(argv[optind])) == '+') {
X            c_time = time(0);
X            c_time += 60 * atoi(++(argv[optind]));
X            tp = localtime(&c_time);
X        } else if ((c = atoi(argv[optind])) >= 0) {
X            c_time = time(0);
X            tp = localtime(&c_time);
X            tp->tm_hour = c / 100;
X            tp->tm_min = c % 100;
X
X            if ((tp->tm_hour > 23) || (tp->tm_min > 59)) {
X                fprintf(stderr, "Illegal time format.\n");
X                return(1);
X            }
X        }
X    }
X    if (c_time <= 0) {
X        fprintf(stderr, "Usage: %s [-d min] [-l min] now [\"message\"]\n",
X                argv[0]);
X        fprintf(stderr, "       %s [-d min] [-l min] +dd [\"message\"]\n",
X                argv[0]);
X        fprintf(stderr, "       %s [-d min] [-l min] HHMM [\"message\"]\n",
X                argv[0]);
X        return(1);
X    }
X    /* do we have a shutdown message? */
X
X    if (++optind < argc)
X        strcpy(buf, argv[optind++]);
X    else
X        strcpy(buf, message);
X
X    massage(buf);
X
X    if ( sp == NULL ) {
X        fprintf(stderr, "No shutdown file defined in ftpaccess file.\n");
X        return(1);
X    }
X
X    /* 
X    ** Create the system shutdown message file at the location
X    ** specified in the ftpaccess 'shutdown' directive.  This
X    ** is for support of real system users.
X    */
X    c = shutdown_msgfile(shutmsg, buf);
X    
X    /* 
X    ** Determine if the site supports anonymous ftp and if so, create
X    ** the shutdown message file in the anonymous ftp area as well
X    ** so that shutdown works appropriately for both real and guest 
X    ** accounts. Save in anonpath for later comparison.
X    */
X
X    if ((pwent = getpwnam("ftp")) != NULL) {
X         sprintf(anonpath,"%s%s",pwent->pw_dir,shutmsg);
X         c += shutdown_msgfile(anonpath, buf);
X    }
X
#ifdef VIRTUAL
X    /* 
X    ** Search the access file for virtual ftp servers. 
X    ** If found, construct a path to the shutdown message file 
X    ** under the virtual server's root.  Don't duplicate what
X    ** is specified in the "ftp" account directory information.
X    */
X 
X    rewind(accessfile);
X 
X    while (fgets(linebuf,sizeof(linebuf)-1,accessfile) != NULL)  {
X       if (strncasecmp(linebuf,"virtual",7)==0) {
X           if ((sp = strstr(linebuf,"root")) != NULL) {
X               if ((cp = strchr(linebuf,'\n')) != NULL)
X                    *cp = '\0';           /* strip newline */
X
X               sp += 4;                   /* skip past "root" keyword */
X 
X               while (*sp && isspace(*sp)) /* skip whitespace to root path */
X                    sp++;
X               cp = sp;                   
X               while (*sp && !isspace(*sp)) 
X                    sp++;
X               *sp = '\0';               /* truncate blanks, comments etc. */
X
X              sprintf(altmsgpath,"%s%s",cp,shutmsg);
X
X              /*
X              ** Check to see if the virtual path created is
X              ** the base path specified in the "ftp" account
X              ** for anonymous ftp support.  If so, skip it.
X              */
X              if (strcmp(anonpath, altmsgpath))
X                  c += shutdown_msgfile(altmsgpath, buf);
X           }
X       }
X    }
#endif
X    fclose(accessfile);
X    return(c > 0 ? 1: 0);
}
SHAR_EOF
  $shar_touch -am 0304145297 'ftpshut.c' &&
  chmod 0644 'ftpshut.c' ||
  $echo 'restore of' 'ftpshut.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'ftpshut.c:' 'MD5 check failed'
cc8fa7fe45289e8f110378d7670417aa  ftpshut.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ftpshut.c'`"
    test 10032 -eq "$shar_count" ||
    $echo 'ftpshut.c:' 'original size' '10032,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh11075
exit 0