Shell script to monitor tmp folder for uploads

Hello,

We have been having some issues with our users overwriting files, and then not having a backup. What I would love to do, is create a shell script to monitor /tmp, for uploads, and make a copy of the file they are trying to upload before the upload finishes.

Is this possible at all?

Sounds possible, but I'm not sure I fully understand the requirement. If the upload is not finished the file would be incomplete. Do you still want to make copies of the partial files?

Also, is there a way you can recognise these files when compared to all the other junk that appears in /tmp?

I'm trying to make a copy of the file that is being overwritten. So, if a user was trying to upload index.html to /www/index.html, I would want to make a backup of index.html in the same directory, before it's overwritten, (/www/index2008-08-09.html)

Having a program check /proc/pid/fd and compare to your /tmp directory would be very slow. As such, you would have to rewrite the open() function (or sys_open() in the kernel). Either you create a program and use LD_PRELOAD to "stop" the open() function and only allow it to continue after a backup is made or you create a kernel module // modify the kernel to change the system call (sys_open()) or the actual internal function do_open() and also backup before allowing them to continue.

Or, if you just wanna keep it simple, read the documentation on your uploading program and it should allow backups of uploaded files.

If so, change the process for uploading a file.
Instead of a

cp junkfile /tmp/junkfile

Do a

sp_cp junkfile /tmp/junkfile

where you define a script called sp_cp that handles the making of a backup copy.

I have a script I call to make sequential backups. In other words, at first execution it will copy myscript to mysript.001; next execution, it will determine that the copy should create myscript.002

Take a look at the following, as it might give you some ideas.

#! /bin/bash
#
# script to backup a file in current directory
# will read directory analyzing scriptname.???
# take the last ??? & increment by one
# finally cp scriptname to scriptname.###
#
# 07/29/2008,jmg  Program Create

clear
# set variables

# verify correct number of parameters
if [ "$#" -ne 1 ]
   then
      echo "This program makes a copy of a program or script"
      echo "copying from scriptname to scriptname.001 (or next number)"
      echo "[located at /opt/dputils] "
      echo " "
      echo "Incorrect number of arguments"
      echo "command scriptname -- examples are"
      echo "script_bk pcsmain"
      echo "script_bk runedit"
      echo " "
      exit
fi

# read the parameters
scriptname="$1"

# determine if any archive copies currently exist
num_arc=$(ls -l "$scriptname".* 2>/dev/null | wc -l)
if [ $num_arc -ge 999 ]
   then
   echo "Warning - already 999 files; please review versions"
   echo "Program terminating"
   exit
fi

if [ $num_arc -eq 0 ]
   then
      arc_ver="001"
   else
      arc_v=$((num_arc+1))
      arc_ver=$(printf "%.3d" "$arc_v")
fi

# make the actual archive file
echo "Copying "$scriptname" to "$scriptname"."$arc_ver
cp $scriptname $scriptname"."$arc_ver

exit 0

What you could do is have a process sitting checking for uploaded files on a regular basis, and as soon as they appear mv them to another unique name or location (subdirectory?) on the destination filesystem.

Once the ftpd has that output file open it should happily continue writing to it even if you rename it while the upload is still running.

The only thing is that the user uploading the file(s) may be confused by the fact that the file they just uploaded is no longer there, but if you give them sufficient warning that shouldn't be a big problem.

Thanks for all the ideas. I'm not sure what solution I'm going to employ yet, this is a more complicated situation then I had originally thought.