#!/usr/bin/env python

#
# Copyright 2005, 2008 OpenHosting, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# $Id: ovuserfiles,v 1.9 2008/09/19 19:15:09 grisha Exp $


"""

This script produces a list of all "user" files. This is handy for
feeding this list to tools like rsync. User files are files that are
not iunlink.

The paths are printed out relative to VSERVERS_ROOT because this is a
format that rsync prefers.

"""

import sys
import os

from openvps.host import cfg

refroots = [os.path.abspath(p) for p in sys.argv[1:]]
refroots += [r for r in cfg.REFROOTS if r not in refroots]

# weed out non-existent roots
refroots = [r for r in refroots if os.path.exists(r)]

vr_len = len(cfg.VSERVERS_ROOT)


vservers = os.listdir(cfg.VSERVERS_ROOT)

for vserver in vservers:

    if vserver.startswith('.'):
        # this is a temporary file of some sort
        continue

    if vserver in [r.split('/')[-1] for r in refroots]:
        # this is a reference server, skip it
        continue

    # always print the VPS root!
    print vserver
    
    for root, dirs, files in os.walk(os.path.join(cfg.VSERVERS_ROOT, vserver)):

        for path in dirs:
            # always include directories
            print os.path.join(root, path)[vr_len+1:]

        for path in files:

            # for files, the logic is as follows: if the link count is
            # 1, then this is a user file. If it's more than 1, then
            # see if the reference server(s) have a file by the same
            # path and the inodes match; if not - it's a user file.

            relpath =  os.path.join(root, path)[vr_len+1:]

            abspath = os.path.join(root, path)

            try:
            
                stat = os.lstat(abspath)

                if stat.st_nlink == 1:
                    # definitely a user file
                    print relpath
                else:
                    found = 0
                    for refroot in refroots:
                        # is there a file like this
                        r_abspath = os.path.join(refroot, '/'.join(relpath.split('/')[1:]))
                        if os.path.exists(r_abspath):
                            # inodes match?
                            if os.stat(r_abspath).st_ino == stat.st_ino:
                                found = 1
                                break

                    if not found:
                        print relpath
                        
            except OSError:
                # sometimes a file may dissapear while we're looking at it,
                # this would throw OSError, just ignore it.
                pass

###
# do not edit this if you like using emacs
# makes emacs go into python mode
### Local Variables:
### mode:python
### End:
