#!/usr/bin/python """ post upload script for pure-ftpds pure-uploadscript daemon installing: - be sure that fchksum module is available in python $ python setup.py build # python setup.py install - copy the script where you want to use it - run the upload daemon # pure-uploadscript -r /path/to/checkSFV.py -B output: 5fvcheck_5_ok_1_failed_15_missing.txt in that file is stored which files failed/missing and the successfully checked ones are in there with their CRC32 sum - it only checks unchecked files listed in .sfv file, so it's best to upload the .sfv first, because when it comes afterwards checking all files can consume a lot time """ import fchksum import string import os, sys import re ######### # CONFIGURATION ######### sfvusers = ['maced', 'murkas', 'warez'] # if the uploading virtual username is not in that list, the script wont run ######### # SCRIPT ######### # only one argument should be given - the uploaded file name if len(sys.argv) is not 2: print "No arguments given. Using current directory." uploadedfile_path = os.getcwd() uploadedfile_name = "sfvcheck" #sys.exit(1) else: uploadedfile_fullpath = sys.argv[1] uploadedfile_path, uploadedfile_name = os.path.split(uploadedfile_fullpath) # prevent doing anything on a nonexistant file or path! if not os.path.exists(uploadedfile_path): print "path does not exist" sys.exit(1) # get the Environment variables # they are: UPLOAD_SIZE (in bytes), UPLOAD_PERMS (permissions, octal integer), # UPLOAD_UID (numerical), UPLOAD_GID (numerical), UPLOAD_USER (login name, string), # UPLOAD_GROUP (string), UPLOAD_VUSER The full user name, or the virtual user name (127 chars max) . pureftpd_env = None # if environment is not set simulate it if os.environ.has_key('UPLOAD_UID'): pureftpd_env = {} pureftpd_env['UID'] = os.environ['UPLOAD_UID'] pureftpd_env['GID'] = os.environ['UPLOAD_GID'] pureftpd_env['Username'] = os.environ['UPLOAD_VUSER'] if pureftpd_env is not None and pureftpd_env['Username'] not in sfvusers: print "username not in list of to be checked users" sys.exit(1) # The SFV-checking code sfvlist = {} # map of crc32 sums (uppercase) with filename (lowercase) as keys, from the sfv file checkedfiles = {} # map of crc32 sums (uppercase) with actual(!) filename as key, from the sfvcheck file sfvcheck_rexp = re.compile("5fvcheck_[0-9]+_ok_[0-9]+_failed_[0-9]+_missing.txt") sfvfile_rexp = re.compile(".*\\.(sfv|SFV)$") found_dotsfv = 0 # no sfv file was found yet dfiles = os.listdir(uploadedfile_path) for lf in dfiles: fullpath = uploadedfile_path + "/" + lf if sfvcheck_rexp.match(lf): sfvcheck_file = open(fullpath) # 5fv file was found lines = sfvcheck_file.readlines() sfvcheck_file.close() os.remove (fullpath) # remove the old file, a new one will be created for line in lines: if line[0] != ';': filename, sum = string.split(line) checkedfiles[filename] = string.upper(sum) elif sfvfile_rexp.match(lf): found_dotsfv = 1 # sfv file was found sfvfile = open (fullpath) lines = sfvfile.readlines() for line in lines: if line[0] != ';' and len (line) > 8: splitelems = string.split(line) if len(splitelems) == 2: filename, sum = splitelems sfvlist[string.lower(filename)] = string.upper(sum) sfvfile.close() #print dfiles if found_dotsfv is not 1: print "no .sfv file found" sys.exit(1) passed = [] failed = [] notfound = [] notinlist = [] ldfiles = [] if (uploadedfile_name not in sfvlist.keys() \ or string.lower(uploadedfile_name) not in sfvlist.keys()) \ and uploadedfile_name != "sfvcheck": print "file %s is not in listed in SFV-file" % (uploadedfile_name) sys.exit(1) #print "starting check" for f in dfiles: ldfiles.append(string.lower(f)) # create lowercase list of files in that dir fullpath = uploadedfile_path + "/" + f if sfvlist.has_key(string.lower(f)): # if the file of that dir is in the .sfv list sum = sfvlist[string.lower(f)] if checkedfiles.has_key(f) and checkedfiles[f] == sum: # if the file was checked and crc32 sum is the same in both lists passed.append(f + " " + sum) continue checksum, filesize = fchksum.fcrc32t(fullpath) checksum = string.upper(checksum) if checksum == sum: passed.append(f + " " + checksum) else: failed.append(f + " - failed!") else: notinlist.append(f + " - not in .sfv list") # check for missing files for f, sum in sfvlist.items(): if string.lower(f) not in ldfiles: notfound.append(f + " - not found!") """ for f, sum in fiter: fullpath = uploadedfile_path + "/" + f sum = string.upper(sum) if os.path.exists(fullpath): if checkedfiles.has_key(f) and checkedfiles[f] == sum: passed.append(f + " " + sum) continue checksum, filesize = fchksum.fcrc32t(fullpath) checksum = string.upper(checksum) if files.has_key(f) and files[f] == checksum: #print f + "passed" passed.append(f + " " + checksum) else: #print "failed" failed.append(f + " failed!") else: #print "not found" notfound.append(f + " notfound!") """ #print "stopped check" filename = "%s/5fvcheck_%d_ok_%d_failed_%d_missing.txt" % (uploadedfile_path, len(passed), len(failed), len(notfound)) efile = open(filename, "w") efile.write("; created by checkSFV.py\r\n;\r\n"); for putt in failed: efile.write("; " + putt) efile.write("\r\n") efile.write(";\r\n"); for netdo in notfound: efile.write("; " + netdo) efile.write("\r\n") efile.write(";\r\n"); for netdo in notinlist: efile.write("; " + netdo) efile.write("\r\n") efile.write(";\r\n"); for sum in passed: efile.write(sum) efile.write("\r\n") efile.close() if pureftpd_env is not None: os.chown(filename, int (pureftpd_env['UID']), int (pureftpd_env['GID'])) #print files #print checkedfiles