# Path: clam/common/util.py
# def globsymlinks(pattern, recursion=True):
#     for f in glob.glob(pattern):
#         if os.path.islink(f):
#             yield f, os.readlink(f)
#     if recursion:
#         for d in os.listdir(os.path.dirname(pattern)):
#             if os.path.isdir(d):
#                 for linkf,realf in globsymlinks(d + '/' + os.path.basename(pattern),recursion):
#                     yield linkf,realf
# 
# def setdebug(debug):
#     global DEBUG
#     DEBUG = debug
# 
# def setlog(log):
#     global LOG
#     LOG = log
# 
# def setlogfile(filename):
#     global LOG, DEBUGLOG
#     LOG = DEBUGLOG = io.open(filename,'w', encoding='utf-8')
# 
# def printlog(msg):
#     if LOG:
#         now = datetime.datetime.now()
#         LOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + "] " + msg + "\n")
# 
# def printdebug(msg):
#     if DEBUG:
#         now = datetime.datetime.now()
#         DEBUGLOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + " DEBUG] " + msg + "\n")
# 
# def xmlescape(s):
#     begin = -1
#     s2 = ""
#     for i,c in enumerate(s):
#         if c == '&':
#             begin = i
#         elif c == ';':
#             if begin > -1:
#                 s2 += s[begin:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == ' ':
#             if begin != -1:
#                 s2 += "&amp;" + s[begin+1:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == '<':
#             s2 += "&lt;"
#         elif c == '>':
#             s2 += "&gt;"
#         elif c == '"':
#             s2 += "&quot;"
#         elif begin == -1:
#             s2 += c
#     if begin != -1:
#         s2 += "&amp;" + s[begin+1:]
#     s = s2
#     return s
# 
# def withheaders(response, contenttype="text/xml; charset=UTF-8", headers=None):
#     if headers is None: headers = { }
#     response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
#     response.headers['Content-Type'] = contenttype
#     try:
#         for key, value in headers.items():
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     except AttributeError: #no dictionary? could be generator/list of tuples
#         for key, value in headers:
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     return response
# 
# def computediskusage(path):
#     total_size = 0
#     total_files = 0
#     for dirpath, dirnames, filenames in os.walk(path): #pylint: disable=unused-variable
#         for f in filenames:
#             fp = os.path.join(dirpath, f)
#             try:
#                 total_size += os.path.getsize(fp)
#                 total_files += 1
#             except:
#                 #may happen in case of dangling symlinks
#                 pass
#     return total_size / 1024 / 1024, total_files #MB


import shutil
import os
import io
import stat
import subprocess
import importlib
import glob
import sys
import datetime
import random
import re
import hashlib
import argparse
import time
import socket
import json
import mimetypes
import flask
import werkzeug
import requests
import base64
import copy
import clam.common.status
import clam.common.parameters
import clam.common.formats
import clam.common.auth
import clam.common.oauth
import clam.common.data
import clam.common.viewers
import clam.config.defaults as settings #will be overridden by real settings later
    import MySQLdb
    import foliatools
    import uwsgi
from clam.common.util import globsymlinks, setdebug, setlog, setlogfile, printlog, printdebug, xmlescape, withheaders, computediskusage
from urllib.parse import urlencode, unquote
    from requests_oauthlib import OAuth2Session
        from werkzeug.debug import DebuggedApplication
                        #And create symbolic link for inputtemplates
                        linkfilename = os.path.dirname(filename)
                        if linkfilename: linkfilename += '/'
                        linkfilename += '.' + os.path.basename(filename) + '.INPUTTEMPLATE' + '.' + inputtemplate.id + '.' + str(nextseq)
                        os.symlink(Project.path(project, user) + 'input/' + filename, Project.path(project, user) + 'input/' + linkfilename)
                    else:
                        printdebug('(Validation error)')
                        #Too bad, everything worked out but the file itself doesn't validate.
                        #output += "<valid>no</valid>"
                        jsonoutput['error'] = fatalerror = "The file did not validate, it is not in the proper expected format."
                        jsonoutput['success'] = False
                        output += "<error>" + xmlescape(fatalerror) + "</error>"
                        #remove upload
                        os.unlink(Project.path(project, user) + 'input/' + filename)


        output += "</upload>\n"

    output += "</clamupload>"



    if returntype == 'boolean':
        return jsonoutput['success']
    elif fatalerror:
        #fatal error return error message with 403 code
        printlog('Fatal Error during upload: ' + fatalerror)
        return errorresponse(fatalerror,403, output)
    elif errors:
        #parameter errors, return XML output with 403 code

# Path: clam/common/util.py
# def globsymlinks(pattern, recursion=True):
#     for f in glob.glob(pattern):
#         if os.path.islink(f):
#             yield f, os.readlink(f)
#     if recursion:
#         for d in os.listdir(os.path.dirname(pattern)):
#             if os.path.isdir(d):
#                 for linkf,realf in globsymlinks(d + '/' + os.path.basename(pattern),recursion):
#                     yield linkf,realf
# 
# def setdebug(debug):
#     global DEBUG
#     DEBUG = debug
# 
# def setlog(log):
#     global LOG
#     LOG = log
# 
# def setlogfile(filename):
#     global LOG, DEBUGLOG
#     LOG = DEBUGLOG = io.open(filename,'w', encoding='utf-8')
# 
# def printlog(msg):
#     if LOG:
#         now = datetime.datetime.now()
#         LOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + "] " + msg + "\n")
# 
# def printdebug(msg):
#     if DEBUG:
#         now = datetime.datetime.now()
#         DEBUGLOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + " DEBUG] " + msg + "\n")
# 
# def xmlescape(s):
#     begin = -1
#     s2 = ""
#     for i,c in enumerate(s):
#         if c == '&':
#             begin = i
#         elif c == ';':
#             if begin > -1:
#                 s2 += s[begin:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == ' ':
#             if begin != -1:
#                 s2 += "&amp;" + s[begin+1:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == '<':
#             s2 += "&lt;"
#         elif c == '>':
#             s2 += "&gt;"
#         elif c == '"':
#             s2 += "&quot;"
#         elif begin == -1:
#             s2 += c
#     if begin != -1:
#         s2 += "&amp;" + s[begin+1:]
#     s = s2
#     return s
# 
# def withheaders(response, contenttype="text/xml; charset=UTF-8", headers=None):
#     if headers is None: headers = { }
#     response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
#     response.headers['Content-Type'] = contenttype
#     try:
#         for key, value in headers.items():
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     except AttributeError: #no dictionary? could be generator/list of tuples
#         for key, value in headers:
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     return response
# 
# def computediskusage(path):
#     total_size = 0
#     total_files = 0
#     for dirpath, dirnames, filenames in os.walk(path): #pylint: disable=unused-variable
#         for f in filenames:
#             fp = os.path.join(dirpath, f)
#             try:
#                 total_size += os.path.getsize(fp)
#                 total_files += 1
#             except:
#                 #may happen in case of dangling symlinks
#                 pass
#     return total_size / 1024 / 1024, total_files #MB


# Path: clam/clamservice.py
import shutil
import os
import io
import stat
import subprocess
import importlib
import glob
import sys
import datetime
import random
import re
import hashlib
import argparse
import time
import socket
import json
import mimetypes
import flask
import werkzeug
import requests
import base64
import copy
import clam.common.status
import clam.common.parameters
import clam.common.formats
import clam.common.auth
import clam.common.oauth
import clam.common.data
import clam.common.viewers
import clam.config.defaults as settings #will be overridden by real settings later
    import MySQLdb
    import foliatools
    import uwsgi
from clam.common.util import globsymlinks, setdebug, setlog, setlogfile, printlog, printdebug, xmlescape, withheaders, computediskusage
from urllib.parse import urlencode, unquote
    from requests_oauthlib import OAuth2Session
        from werkzeug.debug import DebuggedApplication

                        #And create symbolic link for inputtemplates
                        linkfilename = os.path.dirname(filename)
                        if linkfilename: linkfilename += '/'
                        linkfilename += '.' + os.path.basename(filename) + '.INPUTTEMPLATE' + '.' + inputtemplate.id + '.' + str(nextseq)
                        os.symlink(Project.path(project, user) + 'input/' + filename, Project.path(project, user) + 'input/' + linkfilename)
                    else:
                        printdebug('(Validation error)')
                        #Too bad, everything worked out but the file itself doesn't validate.
                        #output += "<valid>no</valid>"
                        jsonoutput['error'] = fatalerror = "The file did not validate, it is not in the proper expected format."
                        jsonoutput['success'] = False
                        output += "<error>" + xmlescape(fatalerror) + "</error>"
                        #remove upload
                        os.unlink(Project.path(project, user) + 'input/' + filename)


        output += "</upload>\n"

    output += "</clamupload>"



    if returntype == 'boolean':
        return jsonoutput['success']
    elif fatalerror:
        #fatal error return error message with 403 code
        printlog('Fatal Error during upload: ' + fatalerror)
        return errorresponse(fatalerror,403, output)
    elif errors:
        #parameter errors, return XML output with 403 code

        printdebug('There were parameter errors during upload!')